// 004_完成端口.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <windows.h>
#include <stdio.h>
struct MyOverlapped : public OVERLAPPED {
MyOverlapped()
{
// 将OVERLAPPED部分填充为0
memset(this, 0, sizeof(OVERLAPPED));
pBuff = NULL;
}
char *pBuff;
~MyOverlapped() {
if (pBuff) {
delete pBuff;
}
}
};
DWORD WINAPI threadProc(LPVOID pArg)
{
HANDLE hIoComp = (HANDLE)pArg;
DWORD dwBytes = 0;
ULONG_PTR completionKey = 0;
MyOverlapped* pOv=NULL;
BOOL ret = 0;
while ( 1 )
{
ret = GetQueuedCompletionStatus(
hIoComp,
&dwBytes,/*实际完成的字节数*/
&completionKey,/*和文件设备关联在一起的完成键*/
(OVERLAPPED**)&pOv,/*通过ReadFile投递IO任务时传递重叠结构*/
-1/*超时时间*/);
if (ret == FALSE) {
continue;
}
printf("读取偏移:[%d]的IO任务完成, 实际读取到的字节数:%d"
"读取到的内容是:%s",
pOv->Offset,
pOv->InternalHigh,
pOv->pBuff);
delete pOv;
}
return 0;
}
int main()
{
// 1. 创建异步IO方式的文件对象
HANDLE hFile = INVALID_HANDLE_VALUE;
hFile = CreateFile(
L"004_完成端口.cpp",
GENERIC_READ,/*读写方式:只读*/
FILE_SHARE_READ,/*共享方式: 共享读*/
NULL,/*安全描述符*/
OPEN_EXISTING,/*创建标志:存在时才打开*/
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,/*文件属性和标志:正常属性|重叠IO标志 */
NULL);
// 2. 创建一个完成端口对象
SYSTEM_INFO si = { 0 };
GetSystemInfo(&si);
HANDLE hIoComp = CreateIoCompletionPort(
INVALID_HANDLE_VALUE,
NULL,
NULL,
si.dwNumberOfProcessors/*处理器个数*/);
// 3. 将完成端口和文件对象进行绑定
CreateIoCompletionPort(
hFile,/*要和完成端口进行绑定的文件句柄*/
hIoComp,/*绑定到哪个完成端口上*/
0,/*完成键, 和文件句柄关联的值*/
0);
// 4. 创建指定个数线程, 在线程监视完成端口 完成列表的状态
for (int i = 0; i < si.dwNumberOfProcessors; ++i) {
CreateThread(0, 0,&threadProc, hIoComp, 0, 0);
}
DWORD read = 0;
// 5. 发起异步IO任务.
for (int i = 0; i < 100; ++i) {
MyOverlapped* pOv = new MyOverlapped;
pOv->pBuff = new char[50];
memset(pOv->pBuff, 0, 50);
pOv->Offset = i * 40;
ReadFile(hFile, pOv->pBuff, 40, &read, pOv);
}
while ( 1 )
{
Sleep(1000);
}
}