网络编程基础_3.APC队列
#include <stdio.h> #include <windows.h> // 保存 IO 操作的结果 CHAR Buffer1[10] = { 0 }; CHAR Buffer2[10] = { 0 }; // APC: 在线程处于闲暇状态才会调用 VOID WINAPI OverLappendRoutine(DWORD dwErrorCode, DWORD dwNumberOfBytesTransfered, LPOVERLAPPED lpOverlapped) { // 1. 每一个线程都有一个 APC 队列,其中保存的是一些 // 函数,这些函数会在线程处于[可警醒](闲暇)状态时 // 被依次队列,知道所有函数调用结束 // 2. 每当有一个 IO 请求被完成的时候,就会向 APC 队列 // 中添加一个函数并指定对应的参数,添加函数的顺序和 // IO 请求提交的顺序并不一定相同。 // 判断当前的 IO 请求是谁产生的 if (lpOverlapped->hEvent == (HANDLE)0x1) printf("[%d]: %s", 1, Buffer1); else printf("[%d]: %s", 2, Buffer2); } int main() { // 1. 以重叠 IO 的方式打开一个文件 HANDLE FileHandle = CreateFile(L"test.txt", GENERIC_ALL, NULL, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); // 2. 投递第一个 IO 请求,读取 [3 ~ 6] 的字符,使用 Ex 版本的函数,需要提供回调函数 OVERLAPPED OverLapped1 = { 0 }; OverLapped1.Offset = 3; OverLapped1.hEvent = (HANDLE)0x1; // 用于识别是哪一个 IO 请求 ReadFileEx(FileHandle, Buffer1, 4, &OverLapped1, OverLappendRoutine); // 3. 投递第二个 IO 请求,读取 [0 ~ 2] 的字符,初始化一个事件对象 OVERLAPPED OverLapped2 = { 0 }; OverLapped2.hEvent = (HANDLE)0x2; // 用于识别是哪一个 IO 请求 ReadFileEx(FileHandle, Buffer2, 3, &OverLapped2, OverLappendRoutine); // 使用各种等待函数的 Ex 版本设置闲暇状态 SleepEx(0, TRUE); return 0; }