zoukankan      html  css  js  c++  java
  • 内核对象之异步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个线程,相互交替工作。

  • 相关阅读:
    mongodb的sql例子(简单版)
    git上传github上
    git中的版本库,暂存区和工作区
    进程与线程的区别
    mysql 在linux 修改账号密码
    linux 下 yum 安装mysql
    linux 下 修改mysql账号密码
    linux 下开放端口问题
    linux 下安装tomcat
    Ubuntu 配置Tomcat环境(转载)
  • 原文地址:https://www.cnblogs.com/wang-can/p/3340751.html
Copyright © 2011-2022 走看看