• 让可等待的计时器添加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 = -30'000'000LL;//倒计时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  
    ", 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
    ");
     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 }
  • 相关阅读:
    异常介绍
    docker 命令
    acm
    Openfiler能把标准x86/64架构的系统变成一个强大的NAS、SAN存储和IP存储网关
    docker 图解学习
    基于Docker的TensorFlow机器学习框架搭建和实例源码解读
    菜鸟打印控件
    Oracle 12c on Solaris 10 安装文档
    内存对齐小解
    安装oracle 11gr2 rac on solaris
  • 原文地址:https://www.cnblogs.com/1228073191Blog/p/7496443.html
Copyright © 2020-2023  润新知