步骤:
1、CreateIoCompletionPort,创建一个I/O完成端口
2、创建或者打开一个设备,CreateFile,一定要注意它的参数
3、CreateIoCompletionPort,再次使用这个函数,将一个设备加入到I/O完成端口。
4、创建一个线程,并为这个线程需要用到数据时,就在这个前面加个GetQueuedCompletionStatus,这个函数就相当于WaitForSingleObject这个函数,当任务完成时,获得执行权。
对I/O完成端口的个人理解:
1、其实I/O完成端口就相当于可提醒内核对象。
2、I/O完成端口多用来处理异步操作
代码:
#include <iostream>
#include <afx.h>
#include <process.h>
using namespace std;
HANDLE g_hDevice, g_hFileSrc;
char buff[1000];
CRITICAL_SECTION g_cs;
UINT WINAPI WhenCome(PVOID pParame)
{
DWORD dwTransLen = 0;
DWORD dwKey = 0;
LPOVERLAPPED overLap = {0};
BOOL IsOk = GetQueuedCompletionStatus(g_hDevice, &dwTransLen, &dwKey, &overLap, INFINITE);
EnterCriticalSection(&g_cs);
DWORD dwErr = GetLastError();
cout << "Thread: " << dwErr << endl;
LeaveCriticalSection(&g_cs);
if(IsOk)
{
cout << "The Content is:" << buff << endl;
}
else
{
cout << "failed" << endl;
}
return 0;
}
void main()
{
InitializeCriticalSection(&g_cs);
DWORD dwErr;
//创建IO完成端口
g_hDevice = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, NULL, 0);
//打开文件
g_hFileSrc = CreateFile(L"D:\test.txt", GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
//将该设备(文件)与IO完成端口相关联,以获得通知
HANDLE h = CreateIoCompletionPort(g_hFileSrc, g_hDevice, NULL, 0);
if(h == g_hDevice)
cout << "关联成功" << endl;
else
cout << "关联失败" << endl;
OVERLAPPED overLap;
overLap.hEvent = 0;
overLap.Offset = 0;
overLap.OffsetHigh = 0;
ReadFile(g_hFileSrc, buff, 1000, 0, &overLap);
HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, WhenCome, NULL, 0, NULL);
WaitForSingleObject(hThread, 1000);
CloseHandle(g_hDevice);
CloseHandle(g_hFileSrc);
CloseHandle(hThread);
DeleteCriticalSection(&g_cs);
}
结果:
我遇到的问题:
1、一定得注意CreateFile的参数,特别是当我们需要以异步的方式来访问数据的时候,我们需要在dwFlagAndAttributes设置FILE_FLAG_OVERLAPPED。
2、如何你想读取一个文件的内容,并将它放在一个buf中,那么你就不能在dwFlagAndAttributes设置FILE_FLAG_NO_BUFFERING。