zoukankan      html  css  js  c++  java
  • I/O完成端口、异步I/O、APC和线程池(三)——APC

    Alertable IO(告警IO)提供了更有效的异步通知形式。ReadFileEx / WriteFileEx在发出IO请求的同时,提供一个回调函数(APC过程),当IO请求完成后,一旦线程进入可告警状态,回调函数将会执行。
        以下五个函数能够使线程进入告警状态:
        SleepEx
        WaitForSingleObjectEx
        WaitForMultipleObjectsEx
        SignalObjectAndWait
        MsgWaitForMultipleObjectsEx
        线程进入告警状态时,内核将会检查线程的APC队列,如果队列中有APC,将会按FIFO方式依次执行。如果队列为空,线程将会挂起等待事件对象。以后的某个时刻,一旦APC进入队列,线程将会被唤醒执行APC,同时等待函数返回WAIT_IO_COMPLETION。
        QueueUserAPC可以用来人为投递APC,只要目标线程处于告警状态时,APC就能够得到执行。
        使用告警IO的主要缺点是发出IO请求的线程也必须是处理结果的线程,如果一个线程退出时还有未完成的IO请求,那么应用程序将永远丢失IO完成通知。然而以后我们将会看到IO完成端口没有这个限制。
        下面的代码演示了QueueUserAPC的用法。


    DWORD WINAPI WorkThread(PVOID pParam)
    {
        HANDLE Event = (HANDLE)pParam;

        for(;;)
        {
            DWORD dwRet = WaitForSingleObjectEx(Event, INFINITE, TRUE);
            if(dwRet == WAIT_OBJECT_0)
                break;
            else if(dwRet == WAIT_IO_COMPLETION)
                printf("WAIT_IO_COMPLETION\n");
        }

        return 0;
    }

    VOID CALLBACK APCProc(DWORD dwParam)
    {
        printf("%s", (PVOID)dwParam);
    }

    void TestAPC(BOOL bFast)
    {
        HANDLE QuitEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

        HANDLE hThread = CreateThread(NULL,
            0,
            WorkThread,
            (PVOID)QuitEvent,
            0,
            NULL);

        Sleep(100); // Wait for WorkThread initialized.

        for(int i=5; i>0; i--)
        {
            QueueUserAPC(APCProc, hThread, (DWORD)(PVOID)"APC here\n");

            if(!bFast)
                Sleep(1000);
        }

        SetEvent(QuitEvent);
        WaitForSingleObject(hThread, INFINITE);
        CloseHandle(hThread);
    }


    参考书目

    1,    MSDN Library
    2,    《Windows高级编程指南》
    3,    《Windows核心编程》
    4,    《Windows 2000 设备驱动程序设计指南》

  • 相关阅读:
    [android] 安卓消息推送的几种实现方式
    二进制部署 Kubernetes 集群
    nginx location反向代理不对等时的处理
    CentOS7用阿里云Docker Yum源在线安装Docker 17.03.2
    Harbor作为Docker的镜像中心
    Harbor 使用 Helm 一键安装
    MYSQL Innodb逻辑存储结构
    安装Redis 4.0单实例
    Redis慢查询日志
    创建Python数据分析的Docker镜像+Docker自定义镜像commit,Dockerfile方式解析+pull,push,rmi操作
  • 原文地址:https://www.cnblogs.com/snailrun/p/2644858.html
Copyright © 2011-2022 走看看