久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Windows Overlapped I/O詳解

 灞河之濱 2019-06-21

http://www.cnblogs.com/skyofbitbit/p/3650140.html

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

方法一:使用另一個線程進(jìn)行I/O,。這個方案可行,,但是麻煩。                即 CreateThread(…………),;創(chuàng)建一個子線程做其他事情,。      Readfile(^…………);阻塞方式讀數(shù)據(jù),。

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

怎樣使用overlapped I/O:

進(jìn)行I/O操作時,,指定overlapped方式
使用CreateFile (),,將其第6個參數(shù)指定為FILE_FLAG_OVERLAPPED,
就是準(zhǔn)備使用overlapped的方式構(gòu)造或打開文件;
如果采用 overlapped,,那么ReadFile(),、WriteFile()的第5個參數(shù)必須提供一個指針,

指向一個OVERLAPPED結(jié)構(gòu),。 OVERLAPPED用于記錄了當(dāng)前正在操作的文件一些相關(guān)信息,。

//功能:從指定文件的1500位置讀入300個字節(jié)
int main()
{
    BOOL rc;
    HANDLE hFile;
    DWORD numread;
    OVERLAPPED overlap;
    char buf[512];
    char szPath=”c:\\xxxx\xxxx”;
    hFile = CreateFile( szPath,
                    GENERIC_READ,
                    FILE_SHARE_READ|FILE_SHARE_WRITE,
                    NULL,
                    OPEN_EXISTING,
                    FILE_FLAG_OVERLAPPED, // 
以overlapped打開文件
                    NULL
                );

// OVERLAPPED結(jié)構(gòu)實始化為0
    memset(&overlap, 0, sizeof(overlap));
    //指定文件位置是
1500;
    overlap.Offset = 1500;
    
    rc = ReadFile(hFile,buf,300,&numread,&overlap);
    //因為是overlapped操作,ReadFile會將讀文件請求放入讀隊列之后立即返回(false),而不會等到文件讀完才返回
(true)
    if (rc)
    {

…………此處即得到數(shù)據(jù)了,。
       //文件真是被讀完了,rc為true
       // 或當(dāng)數(shù)據(jù)被放入cache中,,或操作系統(tǒng)認(rèn)為它可以很快速地取得數(shù)據(jù),,rc為
true
    }
    else
    {
        if (GetLastError() == ERROR_IO_PENDING)
        {//當(dāng)錯誤是ERROR_IO_PENDING,那意味著讀文件的操作還在進(jìn)行中

         //等候,直到文件讀完
            WaitForSingleObject(hFile, INFINITE);
            rc = GetOverlappedResult(hFile,&overlap,&numread,FALSE);
            //
上面二條語句完成的功能與下面一條語句的功能等價:

一只阻塞等到得到數(shù)據(jù)才繼續(xù)下面,。
            // GetOverlappedResult(hFile,&overlap,&numread,TRUE);
         }
         else
         {
            //
出錯了
        }
    }
    CloseHandle(hFile);
    return EXIT_SUCCESS;
}

在實際工作中,,若有幾個操作同一個文件時,
怎么辦?我們可以利用OVERLAPPED結(jié)構(gòu)中提供的event來解決上面遇到的問題,。

注意,,你所使用的event對象必須是一個MANUAL型的;否則,,可能產(chǎn)生競爭條件,。
int main()
{
    int i;
    BOOL rc;
    char szPath=”x:\\xxxx\xxxx”;
    // 
以overlapped的方式打開文件
    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++)   requests 
同時有N個同時讀取文件
    {
        //
將同一文件按幾個部分按overlapped方式同時讀
        //注意看QueueRequest函數(shù)是如何運做的,每次讀16384個塊
        QueueRequest(i, i*16384, READ_SIZE);
    }
    // 
等候所有操作結(jié)束;
    //隱含條件:當(dāng)一個操作完成時,其對應(yīng)的event對象會被激活

    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會系統(tǒng)被激發(fā)
int QueueRequest(int nIndex, DWORD dwLocation, DWORD dwAmount)
{
    //
構(gòu)造一個MANUAL型的event對象
    ghEvents[nIndex] = CreateEvent(NULL, TRUE, FALSE, NULL),;
    //將此event對象置入OVERLAPPED結(jié)構(gòu)
    gOverlapped[nIndex].hEvent = ghEvents[nIndex];

每個重疊對象對應(yīng)一個事件。
    gOverlapped[nIndex].Offset = dwLocation;
    for (i=0; i<MAX_TRY_COUNT; i++) //
嘗試幾次。
   {
      //
文件ghFile唯一
       rc = ReadFile(ghFile, gBuffers[nIndex],&dwNumread,&gOverlapped[nIndex]);
       if (rc) 
如果立刻讀到數(shù)據(jù)則返回真
         return TRUE;
       err = GetLastError();
       if (err == ERROR_IO_PENDING)
       {
           //
當(dāng)錯誤是ERROR_IO_PENDING,那意味著讀文件的操作還在進(jìn)行中
          return TRUE;
       }
       // 
處理一些可恢復(fù)的錯誤
       if ( err == ERROR_INVALID_USER_BUFFER ||
            err == ERROR_NOT_ENOUGH_QUOTA ||
            err == ERROR_NOT_ENOUGH_MEMORY )
        {
           sleep(50); 
           continue;//
重試
        }
        // 
如果GetLastError()返回的不是以上列出的錯誤,,放棄
        break;
    }

    return -1;

}

程序流程:

1 N個用戶同時讀取一個文件的各個部分,,且每個用戶對應(yīng)一個重疊對象和事件。

2:調(diào)用WaitForMultipleObjects(MAX_REQUESTS, ghEvents, TRUE, INFINITE) 當(dāng)任何一個用戶的讀操作完成時,,函數(shù)停止阻塞,。并且ghEvents中對應(yīng)于的讀取數(shù)據(jù)完畢的用戶的事件被激活。

3:調(diào)用GetOverlappedResult 取得讀取數(shù)據(jù)完畢的用戶編號,。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多