c++++ 中異步文件 i/o 的實現(xiàn)核心在于使用重疊 i/o 和完成端口技術,以避免主線程阻塞。1. 使用 overlapped 結構體發(fā)起異步 i/o 請求,2. 創(chuàng)建并關聯(lián)完成端口以處理完成通知,3. 通過 getqueuedcompletionstatus 等待并處理 i/o 完成結果。此外,需注意錯誤處理和資源管理,如檢查 getlasterror 和關閉句柄。
異步文件 I/O 在 c++ 中實現(xiàn)的核心在于讓文件操作不阻塞主線程,從而提高程序的響應性和并發(fā)性。這通常涉及使用操作系統(tǒng)提供的重疊 I/O (Overlapped I/O) 和完成端口 (Completion Ports) 技術。簡單來說,就是發(fā)起 I/O 請求后立即返回,讓操作系統(tǒng)在后臺處理,完成后通知程序。
解決方案:
首先,我們需要理解重疊 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í)行。
接下來,我們需要處理 I/O 完成的通知。這就是完成端口發(fā)揮作用的地方。
-
創(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; }
-
將文件句柄關聯(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; }
-
發(fā)起異步 I/O 請求: 使用 ReadFile 或 WriteFile 函數(shù)發(fā)起異步 I/O 請求,并將 OVERLAPPED 結構體傳遞給函數(shù)。
-
等待 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 結構體的指針。
-
處理 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 | 成人亚洲欧美久久久久|