zoukankan      html  css  js  c++  java
  • Windows定时器学习

    定时器是一个在特定时间或者规则间隔被激发的内核对象。结合定时器的异步程序调用可以允许回调函数在任何定时器被激发的时候执行。

    通过调用CreateWaitableTimer()可以创建一个定时器,此函数返回一个指向内核对象的句柄。若定时器已经存在,你可以通过使用OpenWaitableTimer()获得一个进程相关的句柄。无论是通过CreateWaitableTimer() 还是通过OpenWaitableTimer()获得的句柄,在不需要定时器时必须释放,方法是使用函数CloseHandle()。

    定时的时间通过调用SetWaitableTimer()来设置,可以设置为一个特定的时刻(如December 16, 1999 at 9:45 PM)或者一个相对的时间(如从现在起每五分钟)。函数SetWaitableTime()定时的时间参数要求LARGE_INTEGER类型。这个值应该符合在结构体FILETIME中描述的格式。如果值是正的,代表一个特定的时刻。如果值是负的,代表以100纳秒为单位的相对时间。你也可以将定时器设置为周期性的自我激发,方法是向SetWaitableTimer()的第三个参数传递一个周期参数(以毫秒为单位)。在CreateWaitableTimer()的第二个参数传递FALSE可以产生一个自动归零的定时器。

    在所有的APC中,要执行一个完全例程则线程必须处于监听状态。完全例程将总是被调用SetWaitableTimer()的相同的线程执行,所以此线程必须将必须其自身置于监听状态。可以调用下面的任何一个监听函数来完成监听状态的设置:
            SleepEx();
            WaitForSingleObjectEx();
            WaitForMultipleObjectsEx();
            MsgWaitForMultipleObjectsEx();
            SignalObjectAndWait();

    CreateWaitableTimer()函数用于创建一个可等待定时器:

    函数原型
    HANDLE WINAPI CreateWaitableTimer(
    LPSECURITY_ATTRIBUTES lpTimerAttributes,
    BOOL bManualReset,
    LPCTSTR lpTimerName);
    
    说明
    lpSemaphoreAttributes
    SECURITY_ATTRIBUTES,指定一个结构,用于设置对象的安全特性。如将参数声明为ByVal As Long,并传递零值,就可使用对象的默认安全设置。
    bManualReset
    Long,如果为TRUE,表示创建一个人工重置计时器;如果为FALSE,则创建一个自动重置计时器。
    lpName
    String,指定可等待计时器对象的名称。用vbNullString可创建一个未命名的计时器对象。如果已经存在拥有这个名字的一个可等待计时器,就直接打开现成的可等待计时器。这个名字可能不与一个现有的互斥体、事件、信号机或文件映射的名称相符。
    

    函数OpenWaitableTimer()用于得到一个已经存在的可等待计时器的句柄,该句柄与当前进程相关联: 

    HANDLE OpenWaitableTimer(  
                        DWORD dwDesiredAccess, /* 访问权限 */  
                        BOOL bInheritHandle, /* 是否允许子进程继承该句柄 */  
                        LPCTSTR lpTimerName /* 要打开的对象名称 */  
    ); 
    

    在创建的时候,可等待的计时器对象总是处于未触发状态。当我们想要触发计时器时,必须调用SetWaitableTimer()函数:

    BOOL SetWaitableTimer(  
                          HANDLE hTimer, /* 想要触发的计时器 */  
                          const LARGE_INTEGER *pDueTime, /* 计时器第一次触发的时间 */  
                          LONG lPeriod, /* 第一次触发后,计时器的触发频度 */  
                          PTIMERAPCROUTINE pfnCompletionRoutine, /* 异步过程调用APC函数 */  
                          LPVOID lpArgToCompletionRoutine, /* APC函数的参数 */  
                          BOOL fResume /* 是否继续执行,一般传FALSE */  
    );

    注意,第2个参数pDutTime和第3个参数lPeriod要联合使用,pDutTime是一个LAGRE_INTEGER结构指针,指明了第一次通知的时间,时间格式是UTC(标准时间),是一个绝对值,如果要设置一个相对值,即让等待定时器在调用SetWaitableTimer函数之后多少时间发出第一次通知,只要传递一个负数给该参数即可,但是该数值必须是100ns的倍数,即单位是100ns。第3个参数指明了以后通知的时间间隔,以毫秒为单位,该参数为0时,表示只有第一次的通知,以后没有通知。

    函数CancelWaitableTimer用来将指定的计时器取消:
    BOOL WINAPI CancelWaitableTimer(HANDLE hTimer);

    注意,以上提到的几个函数需要包含<windows.h>头文件,但是只包含此头文件编译会提示:
    'CreateWaitableTimer' undefined; assuming extern returning int
    需要在包含头文件之前定义#define _WIN32_WINNT 0x0400,这样就可以解决CreateWaitableTimer()找不到的问题了。

    以下是我写的一个简单的例子:

    #define _WIN32_WINNT 0x0400  
    #include <stdio.h>  
    #include <windows.h>  
    
    #define _SECOND 10000000  
    
    void CALLBACK OnTimer(LPVOID lpArgToCompletionRoutine, DWORD dwTimerLowValue, DWORD dwTimerHighValue)  
    {  
        printf("alarm!
    ");  
    }  
    
    int main()  
    {  
        int i;  
        int iRet;  
        LARGE_INTEGER li;  
        HANDLE hTimer = CreateWaitableTimer(NULL, FALSE, NULL);  
        if(hTimer == NULL)  
            return -1;  
        li.QuadPart = -2 * _SECOND;  
        iRet = SetWaitableTimer(hTimer, &li, 1000, OnTimer, NULL, FALSE);  
        if(iRet == 0)  
            return -1;  
        for(i = 0; i < 10; i++)  
        {  
            SleepEx(INFINITE, TRUE);  
        }
        system( "PAUSE "); 
        return 0;  
    }
    

    转自http://blog.csdn.net/nevasun/article/details/7282421

  • 相关阅读:
    git学习(一)
    访问注解(annotation)的几种常见方法
    对于元数据的理解
    常用注解介绍
    深入理解Java的接口和抽象类
    POI依据类型设置导出格式
    java泛型
    java 向上转型和向下转型
    cell设置背景颜色为啥不起作用
    Java反射获取对象VO的属性值(通过Getter方法)
  • 原文地址:https://www.cnblogs.com/alinh/p/7284357.html
Copyright © 2011-2022 走看看