下面是建立IO完成連接埠的函數
//建立一個IO完成連接埠HANDLE CreateNewCompletionPort(DWORD NumberOfConcurrentThreads ){return ( CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,0, NumberOfConcurrentThreads ));}//將裝置與IO連接埠關聯起來BOOL AssociateDeviceWithCompletionPort(HANDLE hCompletionPort, HANDLE hDevice, DWORD dwCompletionKey){//參數2不為NULL,那麼參數4忽略HANDLE h = CreateIoCompletionPort(hDevice, hCompletionPort,dwCompletionKey,0);return (h == hCompletionPort);}
IO完成連接埠有5個基礎的資料結構:
1 裝置列表 包含關聯的裝置
2 IO完成隊列(先入先出)IO請求完成,或者Post一個IO完成請求
3 以釋放線程 (後入先出)從等待線程喚醒處理IO完成請求,或者暫停線程被喚醒
4 以等待線程 已經釋放的線程如果等待了,那麼進入等待線程列表
5 以暫停線程 釋放的被暫停
向裝置發出IO請求,但不把該項的已完成的IO請求添加到IO隊列去,是可以的,具體方法是:
Overlapped.hEvent = CreateEvent(NULL, TRUE,
FALSE,NULL);
Overlapped.hEvent = (HANDLE) ((DWOR_PTR)Overlapped.hEvent | 1 );
ReadFile(...,&Overlapped);
關閉這個事件控制代碼時不要忘記最低位清掉
CloseHandle((Handle)((DWORD_PTR)Overlapped.hEvent & ~1) );
#include <windows.h>#include <stdio.h>#include <process.h>#define COMPLETION_KEY_READ1#define COMPLETION_KEY_WRITE2typedef struct MyData : public OVERLAPPED{LPTSTR m_lpBuffer;LONG m_bufferSize;MyData(){Internal = InternalHigh = 0 ;Offset = OffsetHigh = 0;this->hEvent = NULL;}}MYDATA;long g_fileSize = 0;LONG lReadcount = 0;LONG lWritecount = 0;HANDLE g_hFileRead,g_hFileWrite;MYDATA data1,data2;unsigned WINAPI ThreadFunc(LPVOID lp){HANDLE hIO = (HANDLE)lp;ULONG_PTR comKey = 0;LPOVERLAPPED plov = NULL;MYDATA* pData = NULL;long filereadSize = 0;DWORD dw;const long bufferSize = 4*1024;while(lReadcount > 0 || lWritecount > 0 ){BOOL bok = GetQueuedCompletionStatus(hIO, &dw,&comKey,(LPOVERLAPPED*) &pData, INFINITE);switch(comKey){case COMPLETION_KEY_READ:lReadcount--;WriteFile(g_hFileWrite, pData->m_lpBuffer, bufferSize, &dw, pData);lWritecount++;break;case COMPLETION_KEY_WRITE:lWritecount--;if(filereadSize >= g_fileSize)break;lReadcount++;pData->Offset = filereadSize;pData->OffsetHigh = 0;ReadFile(g_hFileRead,pData->m_lpBuffer, bufferSize, &dw, pData);filereadSize += bufferSize;break;default:break;}}CloseHandle(g_hFileRead);CloseHandle(g_hFileWrite);HANDLE hFile = CreateFile(L"2.txt", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);LARGE_INTEGER ll;ll.QuadPart = g_fileSize;SetFilePointerEx(hFile,ll,NULL,FILE_BEGIN);SetEndOfFile(hFile);return 0;}int main(){HANDLE hIoCp = CreateIoCompletionPort(INVALID_HANDLE_VALUE,0,0,0);g_hFileRead = CreateFile(TEXT("1.txt"),GENERIC_ALL,0,NULL, OPEN_ALWAYS,FILE_FLAG_OVERLAPPED,NULL);g_hFileWrite = CreateFile(TEXT("2.txt"), GENERIC_ALL, 0, NULL, CREATE_ALWAYS, FILE_FLAG_OVERLAPPED,NULL);LARGE_INTEGER lagerFile;GetFileSizeEx(g_hFileRead, &lagerFile);g_fileSize = lagerFile.QuadPart;if(CreateIoCompletionPort(g_hFileRead, hIoCp, COMPLETION_KEY_READ, 0) != hIoCp){return GetLastError();}if (CreateIoCompletionPort(g_hFileWrite, hIoCp, COMPLETION_KEY_WRITE, 0) != hIoCp){return GetLastError();}data1.m_bufferSize = 4 * 1024;data1.m_lpBuffer =(LPTSTR) VirtualAlloc(NULL, data1.m_bufferSize, MEM_COMMIT|MEM_RESERVE,PAGE_READWRITE);data2.m_bufferSize = data1.m_bufferSize;data2.m_lpBuffer = (LPTSTR) VirtualAlloc(NULL, data2.m_bufferSize, MEM_COMMIT|MEM_RESERVE,PAGE_READWRITE);PostQueuedCompletionStatus(hIoCp, 0, COMPLETION_KEY_WRITE, &data1);PostQueuedCompletionStatus(hIoCp, 0, COMPLETION_KEY_WRITE, &data2);lWritecount = 2;HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, ThreadFunc, hIoCp, 0, NULL);WaitForSingleObject(hThread,INFINITE);CloseHandle(hIoCp);system("pause");//getchar();return 0;}