见过网上好多的完成端口和网络通信的文章,呵呵,这里就简单的说说文件异步IO和完成端口,这里仅仅说说读取操作。下面是一些总结,很少有人提及,认真的看过MSDN文档之后得出的,欢迎指正。
这里简单的附上一段异步代码:
#include <process.h> #include <Windows.h> VOID WINAPI rt( __in DWORD dwErrorCode, __in DWORD dwNumberOfBytesTransfered, __inout LPOVERLAPPED lpOverlapped ) { printf("rt call back\n"); } int _tmain(int argc, _TCHAR* argv[]) { OVERLAPPED *ol = new OVERLAPPED; memset(ol, 0, sizeof *ol); HANDLE file = CreateFile("ReadMe.txt", GENERIC_READ, 0, NULL, OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED , NULL); if(file == INVALID_HANDLE_VALUE) { goto mem_free1; } size_t buf_len = 1024; char *buf = new char[buf_len]; if(!buf) { goto mem_free1; } if(!ReadFileEx(file, buf, buf_len, ol, rt)) { goto mem_free; } SleepEx(INFINITE, TRUE); mem_free: delete []buf; mem_free1: delete ol; CloseHandle(file); return 0; }
对于ReadFile,主线程在触发异步操作之后,就需要有另外的线程来做辅助工作,可以使用event事件,这里主要介绍完成端口,没有多少好说的,也贴上代码吧:
#include <process.h> #include <windows.h> //创建一个IO完成端口 HANDLE CreateNewCompletionPort(DWORD dwNumberOfConcurrentThreads) { return( CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, NULL, dwNumberOfConcurrentThreads)); } //将设备与完成端口管理起来 BOOL AssociateDeviceWithCompletionPort(HANDLE hCompletionPort, HANDLE hDevice, DWORD dwCompletionKey) { HANDLE h = CreateIoCompletionPort(hDevice, hCompletionPort, dwCompletionKey, 0); return (h == hCompletionPort); } void reader(void *in) { HANDLE port = (HANDLE)in; DWORD rcv_len = 0; ULONG_PTR my_key = 0; OVERLAPPED *ol1 = NULL; while(1) { if(!GetQueuedCompletionStatus(port, &rcv_len, &my_key, &ol1, INFINITE)) { int err = GetLastError(); continue; } else { _endthread(); } } } int _tmain(int argc, _TCHAR* argv[]) { int key = 12345; HANDLE port = CreateNewCompletionPort(4); if(!port) { int err = GetLastError(); return 0; } HANDLE file = CreateFile("ReadMe.txt", GENERIC_READ, 0, NULL, OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED , NULL); if(file == INVALID_HANDLE_VALUE) { CloseHandle(port); } OVERLAPPED *ol = new OVERLAPPED; memset(ol, 0, sizeof *ol); if(!AssociateDeviceWithCompletionPort(port, file, key)) { int err = GetLastError(); CloseHandle(port); CloseHandle(file); delete ol; return 0; } int buf_len = 1000; char *buf = new char[buf_len]; if(!buf) { CloseHandle(port); CloseHandle(file); delete ol; return 0; } HANDLE h_thread = (HANDLE)_beginthread(reader, 0, port); if(!ReadFile(file, buf, buf_len, NULL, ol)) { int err = GetLastError(); if(err != ERROR_IO_PENDING) { CloseHandle(port); CloseHandle(file); delete ol; WaitForSingleObject(h_thread, INFINITE); return 0; } } WaitForSingleObject(h_thread, INFINITE); CloseHandle(port); CloseHandle(file); delete ol; delete []buf; return 0; }