内核对象之异步IO请求完成时调用一个函数
步骤:
1、创建一个
void CALLBACK OverlappedRountine(
PTP_CALLBACK_INSTANCE pInstance,
PVOID pvContext,
PVOID pOverlapped,
ULONG IoResult,
ULONG_PTR NumberOfBytesTransferred,
PTP_IO pIo)
类似的函数
2、打开一个文件
3、CreateThreadpoolIo,创建一个IO线程池
4、在调用异步操作前都调用一下StartThreadpoolIo这个函数
5、WaitForThreadpoolIoCallbacks(pIo, FALSE);表示等待到所有操作结束。如果为TRUE,则是将未完成的操作结束,并返回。
个人理解:
1、将IO完成后,返回后到的线程指定了,而且是每一个异步操作都会进入到此函数。
2、因为此线程池在内部采用了IO完成端口的方式,所以我们的操作会是顺序,因为在IO完成端口里面维护着一个队列
代码:
#include <iostream> #include <afx.h> #include <stdio.h> using namespace std; byte buf[1000]; void OutPut(byte buffer[], int num) { cout << "数据为:"; if(num > 0) { for (int i = 0; i < num; i++) { printf("%02X ", buffer[i]); } cout << endl; } else cout << " 空 " << endl; } void CALLBACK OverlappedRountine( PTP_CALLBACK_INSTANCE pInstance, PVOID pvContext, PVOID pOverlapped, ULONG IoResult, ULONG_PTR NumberOfBytesTransferred, PTP_IO pIo) { cout << "线程ID:" << GetCurrentThreadId() << endl; OVERLAPPED overLap = *((OVERLAPPED*)pOverlapped); OutPut(buf, NumberOfBytesTransferred); Sleep(2000); } void InitCOM(HANDLE &hCOM) { SetupComm(hCOM, 1024, 512); PurgeComm(hCOM, PURGE_RXABORT | PURGE_RXCLEAR | PURGE_TXABORT | PURGE_TXCLEAR); COMMTIMEOUTS CommTimeout; CommTimeout.ReadIntervalTimeout = 5; CommTimeout.ReadTotalTimeoutConstant = 1000; CommTimeout.ReadTotalTimeoutMultiplier = 5; CommTimeout.WriteTotalTimeoutConstant = 1000; CommTimeout.WriteTotalTimeoutMultiplier = 5; SetCommTimeouts(hCOM, &CommTimeout); DCB dcb; GetCommState(hCOM, &dcb); dcb.BaudRate = 4800; dcb.ByteSize = 8; dcb.Parity = NOPARITY; dcb.StopBits = ONESTOPBIT; dcb.fBinary = TRUE; dcb.fParity = FALSE; SetCommState(hCOM, &dcb); } void main() { HANDLE hCOM = CreateFile(L"COM3", GENERIC_WRITE | GENERIC_READ, 0 , NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); cout << "打开COM的返回代码:" << GetLastError() << endl; PTP_IO pIo = CreateThreadpoolIo(hCOM, OverlappedRountine, NULL, NULL); cout << "创建线程池的返回代码:" << GetLastError() << endl; InitCOM(hCOM); StartThreadpoolIo(pIo); byte data = 0x1a; DWORD dwLen = 0; OVERLAPPED overLap; overLap.hEvent = 0; overLap.Offset = 0; overLap.OffsetHigh = 0; WriteFile(hCOM, &data, sizeof(data), &dwLen, &overLap); OVERLAPPED overLap2; overLap2.hEvent = 0; overLap2.Offset = 0; overLap2.OffsetHigh = 0; for (int i = 0; i < 10; ++i) { StartThreadpoolIo(pIo); ReadFile(hCOM, buf, 1000, &dwLen, &overLap2); } WaitForThreadpoolIoCallbacks(pIo, FALSE); CloseHandle(hCOM); CloseThreadpoolIo(pIo); }
结果:
结果分析:
我们可以发现,此时更加能够体现线程池的特点。2个线程,相互交替工作。