• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            kenlistian

            厚積薄發(fā). 勤為槳,思為帆

               :: 首頁(yè) :: 新隨筆 ::  :: 聚合  :: 管理 ::
              73 隨筆 :: 4 文章 :: 22 評(píng)論 :: 0 Trackbacks

             

            從網(wǎng)上整理的文章,同樣,這只是為了我增加理解記憶而做到得筆記,
            不存在利用價(jià)值,純粹是學(xué)習(xí)和記憶.抄襲也好學(xué)習(xí)也好只是讓人明
            白道理.主要干活的還是自己的程序.

            I/O設(shè)備處理必然讓主程序停下來(lái)干等I/O的完成,
            對(duì)這個(gè)問(wèn)題有

            方法一:使用另一個(gè)線(xiàn)程進(jìn)行I/O。這個(gè)方案可行,但是麻煩。

            方法二:使用overlapped I/O。
              正如書(shū)上所說(shuō):“overlapped I/O是WIN32的一項(xiàng)技術(shù),
                你可以要求操作系統(tǒng)為你傳送數(shù)據(jù),并且在傳送完畢時(shí)通知你。
                這項(xiàng)技術(shù)使你的程序在I/O進(jìn)行過(guò)程中仍然能夠繼續(xù)處理事務(wù)。
                事實(shí)上,操作系統(tǒng)內(nèi)部正是以線(xiàn)程來(lái)I/O完成overlapped I/O。
                你可以獲得線(xiàn)程的所有利益,而不需付出什么痛苦的代價(jià)”。
               

            怎樣使用overlapped I/O:

            進(jìn)行I/O操作時(shí),指定overlapped方式
            使用CreateFile (),將其第6個(gè)參數(shù)指定為FILE_FLAG_OVERLAPPED,
            就是準(zhǔn)備使用overlapped的方式構(gòu)造或打開(kāi)文件;
            如果采用 overlapped,那么ReadFile()、WriteFile()的第5個(gè)參數(shù)必須提供一個(gè)指針,
            指向一個(gè)OVERLAPPED結(jié)構(gòu)。 OVERLAPPED用于記錄了當(dāng)前正在操作的文件一些相關(guān)信息。

            //功能:從指定文件的1500位置讀入300個(gè)字節(jié)
            int main()
            {
                BOOL rc;
                HANDLE hFile;
                DWORD numread;
                OVERLAPPED overlap;
                char buf[512];
                char szPath=”x:\\xxxx\xxxx”;
               
                //檢查系統(tǒng),確定是否支持overlapped,(NT以上操作系統(tǒng)支持OVERLAPPED)
                CheckOsVersion();
                // 以overlapped的方式打開(kāi)文件
                hFile = CreateFile( szPath,
                                GENERIC_READ,
                                FILE_SHARE_READ|FILE_SHARE_WRITE,
                                NULL,
                                OPEN_EXISTING,
                                FILE_FLAG_OVERLAPPED,
                                NULL
                            );

                // OVERLAPPED結(jié)構(gòu)實(shí)始化為0
                memset(&overlap, 0, sizeof(overlap));
                //指定文件位置是1500;
                overlap.Offset = 1500;
               
                rc = ReadFile(hFile,buf,300,&numread,&overlap);
                //因?yàn)槭莖verlapped操作,ReadFile會(huì)將讀文件請(qǐng)求放入讀隊(duì)列之后立即返回(false),
                //而不會(huì)等到文件讀完才返回(true)
                if (rc)
                {
                   //文件真是被讀完了,rc為true
                   // 或當(dāng)數(shù)據(jù)被放入cache中,或操作系統(tǒng)認(rèn)為它可以很快速地取得數(shù)據(jù),rc為true
                }
                else
                {
                    if (GetLastError() == ERROR_IO_PENDING)
                    {//當(dāng)錯(cuò)誤是ERROR_IO_PENDING,那意味著讀文件的操作還在進(jìn)行中
                     //等候,直到文件讀完
                        WaitForSingleObject(hFile, INFINITE);
                        rc = GetOverlappedResult(hFile,&overlap,&numread,FALSE);
                        //上面二條語(yǔ)句完成的功能與下面一條語(yǔ)句的功能等價(jià):
                        // GetOverlappedResult(hFile,&overlap,&numread,TRUE);
                     }
                     else
                     {
                        //出錯(cuò)了
                    }
                }
                CloseHandle(hFile);
                return EXIT_SUCCESS;
            }

            在實(shí)際工作中,若有幾個(gè)操作同一個(gè)文件時(shí),
            怎么辦?我們可以利用OVERLAPPED結(jié)構(gòu)中提供的event來(lái)解決上面遇到的問(wèn)題。
            注意,你所使用的event對(duì)象必須是一個(gè)MANUAL型的;否則,可能產(chǎn)生競(jìng)爭(zhēng)條件。
            原因見(jiàn)書(shū)P159。
            int main()
            {
                int i;
                BOOL rc;
                char szPath=”x:\\xxxx\xxxx”;
                // 以overlapped的方式打開(kāi)文件
                ghFile = CreateFile( szPath,
                                GENERIC_READ,
                                FILE_SHARE_READ|FILE_SHARE_WRITE,
                                NULL,
                                OPEN_EXISTING,
                                FILE_FLAG_OVERLAPPED,
                                NULL
                            );
                for (i=0; i<MAX_REQUESTS; i++)
                {
                    //將同一文件按幾個(gè)部分按overlapped方式同時(shí)讀
                    //注意看QueueRequest函數(shù)是如何運(yùn)做的,每次讀16384個(gè)塊
                    QueueRequest(i, i*16384, READ_SIZE);
                }
                // 等候所有操作結(jié)束;
                //隱含條件:當(dāng)一個(gè)操作完成時(shí),其對(duì)應(yīng)的event對(duì)象會(huì)被激活
                WaitForMultipleObjects(MAX_REQUESTS, ghEvents, TRUE, INFINITE);
                // 收尾操作
                for (i=0; i<MAX_REQUESTS; i++)
                {
                    DWORD dwNumread;
                    rc = GetOverlappedResult(
                                            ghFile,
                                            &gOverlapped[i],
                                            &dwNumread,
                                            FALSE
                                        );
                    CloseHandle(gOverlapped[i].hEvent);
                }
                CloseHandle(ghFile);
                return EXIT_SUCCESS;
            }

            //當(dāng)讀操作完成以后,gOverlapped[nIndex].hEvent會(huì)系統(tǒng)被激發(fā)
            int QueueRequest(int nIndex, DWORD dwLocation, DWORD dwAmount)
            {
                //構(gòu)造一個(gè)MANUAL型的event對(duì)象
                ghEvents[nIndex] = CreateEvent(NULL, TRUE, FALSE, NULL);
                //將此event對(duì)象置入OVERLAPPED結(jié)構(gòu)
                gOverlapped[nIndex].hEvent = ghEvents[nIndex];
                gOverlapped[nIndex].Offset = dwLocation;
                for (i=0; i<MAX_TRY_COUNT; i++)
               {
                  //文件ghFile唯一
                   rc = ReadFile(ghFile, gBuffers[nIndex],&dwNumread,&gOverlapped[nIndex]);
                   if (rc)
                     return TRUE;
                   err = GetLastError();
                   if (err == ERROR_IO_PENDING)
                   {
                       //當(dāng)錯(cuò)誤是ERROR_IO_PENDING,那意味著讀文件的操作還在進(jìn)行中
                      return TRUE;
                   }
                   // 處理一些可恢復(fù)的錯(cuò)誤
                   if ( err == ERROR_INVALID_USER_BUFFER ||
                        err == ERROR_NOT_ENOUGH_QUOTA ||
                        err == ERROR_NOT_ENOUGH_MEMORY )
                    {
                       sleep(50);
                       continue;//重試
                    }
                    // 如果GetLastError()返回的不是以上列出的錯(cuò)誤,放棄
                    break;
                }

                return -1;

            }

             

             

            posted on 2006-05-26 11:40 kenlistian 閱讀(3541) 評(píng)論(2)  編輯 收藏 引用

            評(píng)論

            # re: overlapped I/O的學(xué)習(xí) 2008-01-18 15:14 hzy104@gmail.com
            "事實(shí)上,操作系統(tǒng)內(nèi)部正是以線(xiàn)程來(lái)I/O完成overlapped I/O。"你怎么知道的?  回復(fù)  更多評(píng)論
              

            # re: overlapped I/O的學(xué)習(xí) 2009-11-25 19:59 欣萌
            簡(jiǎn)單明了 謝謝  回復(fù)  更多評(píng)論
              


            只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


            亚洲午夜福利精品久久| 久久精品男人影院| 中文字幕日本人妻久久久免费| 久久精品无码一区二区WWW| 久久精品一区二区国产| 久久久久国产视频电影| 久久ww精品w免费人成| 性做久久久久久久久浪潮| 久久精品aⅴ无码中文字字幕不卡 久久精品aⅴ无码中文字字幕重口 | 久久免费高清视频| 综合久久精品色| 久久亚洲国产欧洲精品一| 人妻无码αv中文字幕久久琪琪布 人妻无码精品久久亚瑟影视 | 久久精品国产99国产精品| 久久www免费人成看片| 久久久久人妻一区二区三区vr| 久久亚洲中文字幕精品一区四| 久久精品国产亚洲AV嫖农村妇女| 久久久精品视频免费观看| 久久精品人人做人人爽97| 色妞色综合久久夜夜| 久久免费视频6| 久久一区二区免费播放| 99久久精品国产毛片| 久久精品国产亚洲av麻豆色欲| 国产欧美久久久精品影院| 亚洲欧洲精品成人久久曰影片| 夜夜亚洲天天久久| 久久99国产精品一区二区| 精品国产乱码久久久久久1区2区 | 久久国产免费| 亚洲精品高清国产一久久| 国内精品久久久久影院优| 亚洲国产精品无码久久98| 伊人久久大香线蕉亚洲| 亚洲香蕉网久久综合影视| 久久久久高潮毛片免费全部播放| 中文字幕无码精品亚洲资源网久久| 亚洲综合熟女久久久30p| 久久精品无码专区免费青青| 97精品伊人久久大香线蕉app|