I/O完成端口(iocp)相关内容学习

参考链接: Windows-driver-samples/filesys/miniFilter/scanner/user at main · microsoft/Windows-driver-samples · GitHub

2,I/O 完成端口 - Win32 apps | Microsoft Learn

  通过阅读微软的I/O完成端口介绍,可以大致了解该机制通常结合异步I/O解决多线程的高并发问题。以scanner/user的代码为例,I/O完成端口的使用分为以下几步:

1,通过CreateIoCompletionPort将文件句柄与端口进行关联,并设置处理异步I/O业务的线程数

    hr = FilterConnectCommunicationPort( ScannerPortName,
                                         0,
                                         NULL,
                                         0,
                                         NULL,
                                         &port );//返回需要关联的文件句柄

    if (IS_ERROR( hr )) {

        printf( "ERROR: Connecting to filter port: 0x%08x\n", hr );
        return 2;
    }

    //
    //  Create a completion port to associate with this handle.
    //
    //关联句柄,设置工作线程数量
    completion = CreateIoCompletionPort( port,
                                         NULL,
                                         0,
                                         threadCount );//工作线程数量

2,创建线程,等待处理I/O业务

    while (TRUE) {

#pragma warning(pop)

        //
        //  Poll for messages from the filter component to scan.
        //
        // 
        // 尝试从指定的 I/O 完成端口取消对 I/O 完成数据包的排队。 如果没有完成数据包排队,
        // 函数将等待与完成端口关联的挂起 I/O 操作完成。
        //
        // 
        //如果没有完成数据包排队,GetQueueCompletionStatus函数就不会返回,相当于阻塞线程执行
        //
        // 若要一次取消多个 I/O 完成数据包的排队,请使用 GetQueuedCompletionStatusEx 函数。 
        //
        result = GetQueuedCompletionStatus( Context->Completion, &outSize, &key, &pOvlp, INFINITE );

        //
        //  Obtain the message: note that the message we sent down via FltGetMessage() may NOT be
        //  the one dequeued off the completion queue: this is solely because there are multiple
        //  threads per single port handle. Any of the FilterGetMessage() issued messages can be
        //  completed in random order - and we will just dequeue a random one.
        //
        //
        //
        //提取核心I/O数据
        message = CONTAINING_RECORD( pOvlp, SCANNER_MESSAGE, Ovlp );

3,调用异步I/O接口

        for (j = 0; j < requestCount; j++) {

            //
            //  Allocate the message.
            //

#pragma prefast(suppress:__WARNING_MEMORY_LEAK, "msg will not be leaked because it is freed in ScannerWorker")
            msg = malloc( sizeof( SCANNER_MESSAGE ) );

            if (msg == NULL) {

                hr = ERROR_NOT_ENOUGH_MEMORY;
                goto main_cleanup;
            }
            //使用异步(重叠I/O)
            memset( &msg->Ovlp, 0, sizeof( OVERLAPPED ) );

            //
            //  Request messages from the filter driver.
            //
            //异步
            //
            //FilterGetMessage 使用重叠I/O会立刻返回执行
            //
            // ScannerWorker 接手处理后续的I/O流程
            //从微型筛选器获取消息
            hr = FilterGetMessage( port,
                                   &msg->MessageHeader,
                                   FIELD_OFFSET( SCANNER_MESSAGE, Ovlp ),
                                   &msg->Ovlp );

            if (hr != HRESULT_FROM_WIN32( ERROR_IO_PENDING )) {

                free( msg );
                goto main_cleanup;
            }
        }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值