非同步裝置IO 《windows核心編程》第10章學習<待續>

來源:互聯網
上載者:User

標籤:

 

非同步IO操作與同步操作區別:
  1. 在CreateFile裡的FILE_FLAG_OVERLAPPED標誌
  2. 非同步作業函數LPOVERLAPPED參數
接收IO請求完成通知
  1. 觸發裝置核心對象
    缺點:同一個裝置核心對象有可能進行多次讀寫操作,這樣第一個完成這個裝置核心對象就會被觸發,所以這種方式不可以使用於這種情形
    void Test1(){    HANDLE hFile = ::CreateFile(_T("aaa.txt"),        GENERIC_READ,        FILE_SHARE_READ,        NULL,        OPEN_EXISTING,        FILE_FLAG_OVERLAPPED,        NULL);    if(!hFile)    {        wcout<<L"CreateFile Failed ErroCode:"<<::GetLastError()<<endl;        return ;    }    DWORD dwFileSize = ::GetFileSize(hFile,0);    wcout<<L"FileSize:"<<dwFileSize<<endl;    char * pFileContent = new char[10000000];    DWORD dwReaded = 0;    OVERLAPPED o_Read = {0};    DWORD bReadDone = ::ReadFile(hFile,        pFileContent,        10000000,        &dwReaded,        &o_Read);    DWORD dwError = ::GetLastError();    if(!bReadDone && (dwError == ERROR_IO_PENDING))    {        WaitForSingleObject(hFile,INFINITE);        bReadDone = TRUE;    }    if(bReadDone)        wcout<<L"I/O Code:"<<o_Read.Internal<<" TransedBytes:"<<o_Read.InternalHigh<<endl;    else        wcout<<"Error:"<<::GetLastError()<<endl;    ::CloseHandle(hFile);    delete [] pFileContent;}
  2. 觸發事件核心對象
    void Test2(){    HANDLE hFile = ::CreateFile(_T("aaa.txt"),        GENERIC_WRITE,        FILE_SHARE_READ,        NULL,        OPEN_EXISTING,        FILE_FLAG_OVERLAPPED,        NULL);    if(!hFile)    {        wcout<<L"CreateFile Failed ErroCode:"<<::GetLastError()<<endl;        return ;    }    DWORD dwFileSize = ::GetFileSize(hFile,0);    wcout<<L"FileSize:"<<dwFileSize<<endl;    LARGE_INTEGER liDis = {0};    LARGE_INTEGER liRet = {0};    ::SetFilePointerEx(hFile,liDis,&liRet,FILE_END);    wcout<<L"PreWrite File Pos:"<<liRet.LowPart<<endl;    char * pFileContent = new char[10000000];    memset(pFileContent,‘z‘,10000000);    DWORD dwReaded = 0;    OVERLAPPED o_Write = {0};    o_Write.Offset = liRet.LowPart;    o_Write.hEvent = ::CreateEvent(NULL,FALSE,FALSE,NULL);    DWORD bReadDone = ::WriteFile(hFile,        pFileContent,        10000000,        &dwReaded,        &o_Write);    DWORD dwError = ::GetLastError();    if(!bReadDone && (dwError == ERROR_IO_PENDING))    {        WaitForSingleObject(o_Write.hEvent,INFINITE);        bReadDone = TRUE;    }    if(bReadDone)        wcout<<L"I/O Code:"<<o_Write.Internal<<" TransedBytes:"<<o_Write.InternalHigh<<endl;    else        wcout<<"Error:"<<::GetLastError()<<endl;    ::CloseHandle(hFile);    delete [] pFileContent;}
  3. 可提醒IO
    void Test3(){    //可提醒IO    HANDLE hFile = ::CreateFile(_T("aaa.txt"),        GENERIC_WRITE,        FILE_SHARE_READ,        NULL,        OPEN_EXISTING,        FILE_FLAG_OVERLAPPED,        NULL);    if(!hFile)    {        wcout<<L"CreateFile Failed ErroCode:"<<::GetLastError()<<endl;        return ;    }    DWORD dwFileSize = ::GetFileSize(hFile,0);    wcout<<L"FileSize:"<<dwFileSize<<endl;    LARGE_INTEGER liDis = {0};    LARGE_INTEGER liRet = {0};    ::SetFilePointerEx(hFile,liDis,&liRet,FILE_END);    wcout<<L"PreWrite File Pos:"<<liRet.LowPart<<endl;    char * pFileContent = new char[10000000];    memset(pFileContent,‘g‘,10000000);    DWORD dwReaded = 0;    OVERLAPPED o_Write = {0};    o_Write.Offset = liRet.LowPart;    DWORD bReadDone = ::WriteFileEx(hFile,        pFileContent,        10000000,        &o_Write,        FileIOCompletionRoutine);    ::CloseHandle(hFile);    SleepEx(10000,TRUE);    delete [] pFileContent;}

    可提醒IO的優劣:
    (1)由於回呼函數的原因,最終不得不把大量資訊放在全域變數中。使代碼變的更加複雜
    (2)發出請求線程和完成處理必須是同一線程,沒有達到線程負載平衡
    可提醒IO相關函數
    (1)QueueUserAPC函數
         a.這個函數允許我們手動增加APC項。
         b.可以強制線程退出等待狀態比如WaitForSingleObjectEx 以下是範例程式碼
     
    VOID WINAPI APCFunc(ULONG_PTR pvParam){    //Nothing To Do}UINT WINAPI ThreadFunc(PVOID pvParam){    wcout<<L"start Wait...."<<endl;    DWORD dw = ::WaitForSingleObjectEx(pvParam,INFINITE,TRUE);    if(dw == WAIT_OBJECT_0)    {        wcout<<L"Event signaled"<<endl;        return 0;    }    else if(dw == WAIT_IO_COMPLETION)    {        wcout<<L"QueueUserApc Forced us out of a wait state"<<endl;        return 0;    }    return 0;}void Test4(){    //利用QueueUserApc來停止線程等待    HANDLE hEvent = ::CreateEvent(NULL,FALSE,FALSE,NULL);    HANDLE hThread = (HANDLE) _beginthreadex(NULL,0,ThreadFunc,hEvent,0,NULL);    Sleep(5000);    QueueUserAPC(APCFunc,hThread,NULL);    WaitForSingleObject(hThread,INFINITE);    CloseHandle(hThread);    CloseHandle(hEvent);}
     
     
  4. I/O完成連接埠
    待續

非同步裝置IO 《windows核心編程》第10章學習<待續>

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.