如何用C++實現(xiàn)異步文件IO 重疊IO和完成端口技術解析

c++++ 中異步文件 i/o 的實現(xiàn)核心在于使用重疊 i/o 和完成端口技術,以避免線程阻塞。1. 使用 overlapped 結構體發(fā)起異步 i/o 請求,2. 創(chuàng)建并關聯(lián)完成端口以處理完成通知,3. 通過 getqueuedcompletionstatus 等待并處理 i/o 完成結果。此外,需注意錯誤處理和資源管理,如檢查 getlasterror 和關閉句柄。

如何用C++實現(xiàn)異步文件IO 重疊IO和完成端口技術解析

異步文件 I/O 在 c++ 中實現(xiàn)的核心在于讓文件操作不阻塞主線程,從而提高程序的響應性和并發(fā)性。這通常涉及使用操作系統(tǒng)提供的重疊 I/O (Overlapped I/O) 和完成端口 (Completion Ports) 技術。簡單來說,就是發(fā)起 I/O 請求后立即返回,讓操作系統(tǒng)在后臺處理,完成后通知程序。

如何用C++實現(xiàn)異步文件IO 重疊IO和完成端口技術解析

解決方案:

如何用C++實現(xiàn)異步文件IO 重疊IO和完成端口技術解析

首先,我們需要理解重疊 I/O 的概念。重疊 I/O 允許我們發(fā)起一個 I/O 操作,而無需等待其完成。我們需要一個 OVERLAPPED 結構體來傳遞 I/O 請求的相關信息。

立即學習C++免費學習筆記(深入)”;

#include <iostream> #include <fstream> #include <windows.h>  bool AsyncReadFile(HANDLE hFile, LPVOID buffer, DWORD bytesToRead, LPOVERLAPPED pOverlapped) {     return ReadFile(hFile, buffer, bytesToRead, NULL, pOverlapped); }

這段代碼只是一個簡單的開始,它展示了如何使用 ReadFile 函數(shù)發(fā)起一個異步讀取操作。關鍵在于最后一個參數(shù) pOverlapped,它告訴操作系統(tǒng)這是一個異步操作。如果 ReadFile 返回 FALSE,并不一定意味著失敗,而是可能操作正在進行中,需要檢查 GetLastError() 的返回值。如果是 ERROR_IO_PENDING,則表示操作正在異步執(zhí)行。

如何用C++實現(xiàn)異步文件IO 重疊IO和完成端口技術解析

接下來,我們需要處理 I/O 完成的通知。這就是完成端口發(fā)揮作用的地方。

  1. 創(chuàng)建完成端口: 使用 CreateIoCompletionPort 函數(shù)創(chuàng)建一個完成端口。

    HANDLE hCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0); if (hCompletionPort == NULL) {     std::cerr << "CreateIoCompletionPort failed: " << GetLastError() << std::endl;     return 1; }
  2. 將文件句柄關聯(lián)到完成端口: 使用 CreateIoCompletionPort 函數(shù)將文件句柄與完成端口關聯(lián)起來。

    HANDLE hFile = CreateFile(L"test.txt", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); if (hFile == INVALID_HANDLE_VALUE) {     std::cerr << "CreateFile failed: " << GetLastError() << std::endl;     return 1; }  HANDLE hAssociatedPort = CreateIoCompletionPort(hFile, hCompletionPort, (ULONG_PTR)hFile, 0); if (hAssociatedPort == NULL) {     std::cerr << "Associate file handle with completion port failed: " << GetLastError() << std::endl;     return 1; }
  3. 發(fā)起異步 I/O 請求: 使用 ReadFile 或 WriteFile 函數(shù)發(fā)起異步 I/O 請求,并將 OVERLAPPED 結構體傳遞給函數(shù)。

  4. 等待 I/O 完成: 使用 GetQueuedCompletionStatus 函數(shù)等待 I/O 完成的通知。

    DWORD bytesTransferred; ULONG_PTR completionKey; LPOVERLAPPED pOverlapped;  BOOL bRet = GetQueuedCompletionStatus(hCompletionPort, &bytesTransferred, &completionKey, &pOverlapped, INFINITE); if (bRet == FALSE) {     std::cerr << "GetQueuedCompletionStatus failed: " << GetLastError() << std::endl;     return 1; }  std::cout << "Bytes transferred: " << bytesTransferred << std::endl;

    GetQueuedCompletionStatus 會一直阻塞,直到完成端口收到一個 I/O 完成的通知。當 I/O 完成時,bytesTransferred 變量會包含實際傳輸?shù)淖止?jié)數(shù),completionKey 變量會包含與文件句柄關聯(lián)的完成鍵,pOverlapped 變量會包含指向 OVERLAPPED 結構體的指針。

  5. 處理 I/O 完成: 在 GetQueuedCompletionStatus 返回后,我們可以處理 I/O 操作的結果。例如,可以檢查 bytesTransferred 變量的值,以確定實際傳輸?shù)淖止?jié)數(shù)。

完整的示例代碼:

#include <iostream> #include <fstream> #include <windows.h>  int main() {     HANDLE hCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);     if (hCompletionPort == NULL) {         std::cerr << "CreateIoCompletionPort failed: " << GetLastError() << std::endl;         return 1;     }      HANDLE hFile = CreateFile(L"test.txt", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);     if (hFile == INVALID_HANDLE_VALUE) {         std::cerr << "CreateFile failed: " << GetLastError() << std::endl;         return 1;     }      HANDLE hAssociatedPort = CreateIoCompletionPort(hFile, hCompletionPort, (ULONG_PTR)hFile, 0);     if (hAssociatedPort == NULL) {         std::cerr << "Associate file handle with completion port failed: " << GetLastError() << std::endl;         return 1;     }      char buffer[1024];     OVERLAPPED overlapped = {0};     overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); //手動重置事件      if (!ReadFile(hFile, buffer, sizeof(buffer) - 1, NULL, &overlapped)) {         if (GetLastError() != ERROR_IO_PENDING) {             std::cerr << "ReadFile failed: " << GetLastError() << std::endl;             CloseHandle(hFile);             CloseHandle(hCompletionPort);             return 1;         }     }      DWORD bytesTransferred;     ULONG_PTR completionKey;     LPOVERLAPPED pOverlapped;      BOOL bRet = GetQueuedCompletionStatus(hCompletionPort, &bytesTransferred, &completionKey, &pOverlapped, INFINITE);     if (bRet == FALSE) {         std::cerr << "GetQueuedCompletionStatus failed: " << GetLastError() << std::endl;         CloseHandle(hFile);         CloseHandle(hCompletionPort);         return 1;     }      buffer[bytesTransferred] = '

久久国产欧美日韩精品|
久久激情亚洲精品无码?V|
久久精品人人做人人爽电影|
午夜不卡久久精品无码免费|
久久精品国产精品青草app|
大蕉久久伊人中文字幕|
久久亚洲日韩看片无码|
狠狠色婷婷综合天天久久丁香|
久久se精品一区二区影院|
色偷偷偷久久伊人大杳蕉|
久久久久久毛片免费看|
97久久久精品综合88久久|
日韩中文久久|
久久国产成人|
久久精品国产69国产精品亚洲|
久久久国产打桩机|
久久久艹|
久久久精品久久久久特色影视|
无码日韩人妻精品久久蜜桃|
亚洲国产成人精品女人久久久|
精品综合久久久久久97超人|
久久久一本精品99久久精品88|
思思久久99热免费精品6|
亚洲国产精品久久久久婷婷软件|
亚洲国产另类久久久精品小说
|
久久综合伊人77777|
久久精品国产亚洲AV无码麻豆
|
99久久国产免费福利|
日韩久久久久久中文人妻|
久久精品国产日本波多野结衣|
久久夜色撩人精品国产|
精品久久久无码中文字幕天天
|
久久亚洲私人国产精品|
99精品国产免费久久久久久下载
|
国内精品久久久久久麻豆|
久久精品国产久精国产|
9191精品国产免费久久|
国产精品日韩深夜福利久久|
久久精品一区二区影院|
亚洲国产成人久久综合一区77
|
成人亚洲欧美久久久久|