• 内核对象之异步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个线程,相互交替工作。

  • 相关阅读:
    实战 Windows下搭建Objectivec的编译环境
    C# 协变和逆变 精解(直观明了,简单易懂)
    求两个字符串的最大公共串
    [C++][数据结构]队列(queue)的实现
    转换一个矩阵(2维数组)为HTML Table
    [C++][数据结构][算法]单链式结构的深拷贝
    LaTeX 中的特殊符号
    [C++11][数据结构]自己的双链表实现
    现代诗十则
    [C++11][算法][穷举]输出背包问题的所有可满足解
  • 原文地址:https://www.cnblogs.com/wang-can/p/3340751.html
Copyright © 2020-2023  润新知