让可等待的计时器添加APC调用

Posted 生如逆旅 一苇以航

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了让可等待的计时器添加APC调用相关的知识,希望对你有一定的参考价值。

  1 // TimerAPCRoutine.cpp : 定义控制台应用程序的入口点。
  2 //
  3 
  4 #include "stdafx.h"
  5 #include <windows.h>
  6 #include <iostream>
  7 #include <time.h>
  8 
  9 
 10 using namespace std;
 11 
 12 
 13 void GetSystemTime();
 14 VOID CALLBACK TimerAPCRoutinue(
 15     _In_opt_ LPVOID lpArgToCompletionRoutine,
 16     _In_     DWORD  dwTimerLowValue,
 17     _In_     DWORD  dwTimerHighValue
 18 );
 19 
 20 
 21 
 22 
 23 int main()
 24 {
 25     LARGE_INTEGER DueTime;
 26     DueTime.QuadPart = -30000000LL;//倒计时3秒 从调用到显示的时间
 27 
 28     HANDLE TimeHandle = NULL;
 29     TimeHandle =
 30         CreateWaitableTimer(
 31             NULL,
 32             //TRUE, //BOOL  bManualReset
 33             FALSE,
 34             NULL
 35         );
 36 
 37     if (!SetWaitableTimer(
 38         TimeHandle, 
 39         &DueTime, //第一次,The time after which the state of the timer is to be set to signaled
 40         1000, //第二次执行与第一次执行的间隔   周期 1秒       The period of the timer
 41         TimerAPCRoutinue, 
 42         NULL, 
 43         0
 44     )
 45         )
 46     {
 47         printf("SetWaitableTimer FAIL: %d  \r\n", GetLastError());
 48         return 0;
 49     }
 50 
 51     //进入可提醒状态  可提醒IO 
 52     /*
 53     while (1)
 54     {
 55         WaitForSingleObjectEx(TimeHandle, INFINITE,TRUE);
 56     }
 57     */
 58     //这里的话只能走2次,应该是等待时间的问题
 59     /*
 60     指针放到APC中,还没有执行,后面一次就来了。要使用SleepEx
 61     感觉这里WaitFoeSingleObjectEx 不同的地方
 62     */
 63     for (int i = 0;i < 5; i++)
 64     {
 65         //WaitForSingleObjectEx(TimeHandle, INFINITE,TRUE); //阻塞不住
 66         /*
 67         windows核心编程 p250
 68         线程不应该在等待一个计时器句柄的同时以可提醒的方式等待同一个计时器。
 69         
 70         HANDLE hTimer = CreateWaitableTimer(NULL,FALSE,NULL);
 71         SetWaitableTimer(hTimer,...,TimerAPCRoutinyr,...);
 72         WaitForSingleObjectEx(hTimer,INFINTE,TRUE);
 73 
 74         我们不应该编写此类代码,因为对WaitForSingleObjectEx的调用
 75         实际上会等待计时器两次:一次是可提醒的,另一次是内核对象句柄。
 76         当计时器被触发的时候,等待成功,线程被唤醒,这使线程退出可提醒状态
 77         APC函数没有被调用。我们一般很少有理由要在使用可等待计时器的同时使用APC函数,
 78         因为我们总是可以先等待计时器被触发,然后在执行我们想要的操作。
 79 
 80         */
 81         
 82 
 83         SleepEx(
 84             INFINITE,     // Wait forever
 85             TRUE);
 86     }
 87     
 88     
 89     printf("input any key to exit\r\n");
 90     getchar();
 91 
 92     return 0;
 93 }
 94 
 95 VOID CALLBACK TimerAPCRoutinue(
 96     _In_opt_ LPVOID lpArgToCompletionRoutine,
 97     _In_     DWORD  dwTimerLowValue,
 98     _In_     DWORD  dwTimerHighValue
 99 )
100 {
101     GetSystemTime();
102 
103 }
104 
105 void GetSystemTime()
106 {
107     time_t t = time(0);
108     char tmp[64];
109     strftime(tmp, sizeof(tmp), "%Y/%m/%d %X %A 本年第%j天 %z", localtime(&t));
110     puts(tmp);
111 }

 

以上是关于让可等待的计时器添加APC调用的主要内容,如果未能解决你的问题,请参考以下文章

JUC并发编程 共享模式之工具 JUC CountdownLatch(倒计时锁) -- CountdownLatch应用(等待多个线程准备完毕( 可以覆盖上次的打印内)等待多个远程调用结束)(代码片段

通过异步程序调用(APC)实现的定时功能

注入理解之APC注入

python使用上下文对代码片段进行计时,非装饰器

PHP 缓存插件之 Zend Opcache ( 取代 APC )

深入学习APC