• 用户层APC队列使用


    一 参考

    https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-queueuserapc

    <<windows核心编程>> 第5版

    二 每个线程都有一个APC队列, 在线程处于可警醒状态时, 线程会执行APC队列中apc函数

      经过以上参考文章加上测试发现, APC队列中的函数会在以下3个时机调用

      1 线程已经创建, 系统在调用线程函数时会检查APC队列, 如果不为空, 则调用APC队列中的apc函数, 直到队列为空后, 才开始调用线程函数

      2 线程通过WaitForSingleObjectEx等函数进入可警醒状态时, 会先检查APC队列, 如果不为空, 则调用APC队列中的apc函数, 直到队列为空后, 才开始等待要等待的对象, 此时如果要等待的对象没有进入激发态且没有超时WaitForSingleObjectEx不会返回

      3 线程通过WaitForSingleObjectEx等函数进入可警醒状态时, APC队列为空, 且要等待的对象没有进入激发态, 也没有超时, 则线程进入睡眠等待状态, 此时往该APC队列添加APC函数后, 该线程会被唤醒执行完所有APC队列中的函数, 然后不去看要等待的对象是否进入激发态, 立即从WaitForSingleObjectEx中返回, 返回值是WAIT_IO_COMPLETION 

    测试代码如下

     1 #include <windows.h>
     2 #include <iostream>
     3 #include <process.h>
     4 
     5 HANDLE hEvent = NULL;
     6 HANDLE HMainEvent = NULL;
     7 DWORD WINAPI TestProc(LPVOID lpThreadParameter)
     8 {
     9     printf("thread start
    ");
    10     SetEvent(HMainEvent);
    11     if (hEvent && hEvent != INVALID_HANDLE_VALUE)
    12     {
    13         printf("waitfor start
    ");
    14         DWORD ret = WaitForSingleObjectEx(hEvent, INFINITE, TRUE);
    15         //WAIT_OBJECT_0
    16         printf("waitfor ret= 0x%08x
    ", ret);
    17     }
    18     printf("thread end
    ");
    19     return 0;
    20 }
    21 VOID NTAPI TestAPC(ULONG_PTR Parameter)
    22 {
    23     printf("apc func start index=%u
    ",Parameter);
    24 }
    25 int main(int argc, char **argv, char **env)
    26 {
    27     HANDLE hT = NULL;
    28     hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    29     HMainEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    30 
    31     if (hEvent)
    32     {
    33         hT = (HANDLE)_beginthreadex(NULL, 0, (_beginthreadex_proc_type)TestProc, NULL, 0, NULL);
    34         if (hT && hT != INVALID_HANDLE_VALUE)
    35         {
    36             WaitForSingleObject(HMainEvent, INFINITE);
    37             //Sleep(2000);
    38             ULONG_PTR index = 1;
    39             for(;index <100;++index)
    40             {
    41                 QueueUserAPC(TestAPC, hT, index);
    42             }
    43             Sleep(2000);
    44             SetEvent(hEvent);
    45             WaitForSingleObject(hT, INFINITE);
    46         }
    47     }
    48     CloseHandle(hEvent);
    49     CloseHandle(HMainEvent);
    50     CloseHandle(hT);
    51     system("pause");
    52     return 0;
    53 }
  • 相关阅读:
    最近在学习vala,并打算用它写点东西, 先上个习作 -- popplersample
    GTK# 学习笔记
    monodevelop2.0在SmartQ5上成功运行
    c, cs, vala 性能简单测试
    在Q5上用vala写程序
    树结构型数据在基于关系型数据库的分布式应用的解决方案
    常用常忘的delegate,记一下。
    JSON
    HTML5脚本编程
    event事件对象
  • 原文地址:https://www.cnblogs.com/talenth/p/10286620.html
Copyright © 2020-2023  润新知