I/O异步之I/O完成端口

步骤:

  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。

原文地址:https://www.cnblogs.com/wang-can/p/3336765.html