016 可等待计时器对象.6

Posted ☆﹎夜﹎☆

tags:

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

可等待计时器对象.

  ● CreateWaitableTimer

  函数原型

1 HANDLE WINAPI CreateWaitableTimer(
2   _In_opt_ LPSECURITY_ATTRIBUTES lpTimerAttributes,
3   _In_     BOOL                  bManualReset,
4   _In_opt_ LPCTSTR               lpTimerName
5 );

    参数1:lpSemaphoreAttributes

    SECURITY_ATTRIBUTES,指定一个结构,用于设置对象的安全特性。如将参数声明为ByVal As Long,并传递零值,就可使用对象的默认安全设置。

   ○ 参数2bManualReset
    Long,如果为TRUE,表示创建一个人工重置计时器;如果为FALSE,则创建一个自动重置计时器。

   ○ 参数3lpName
    String,指定可等待计时器对象的名称。用vbNullString可创建一个未命名的计时器对象。如果已经存在拥有这个名字的一个可等待计时器,就直接打开现成的可等待计时器。这个名字可能不与一个现有的互斥体、事件、信号机或文件映射的名称相符。

    使用人工重置,则计时结束后所有的等待线程均变为可调度线程;使用自动重置,则只有一个线程变为可调度线程。

 

  ● SetWaitableTimer

  函数原型

1 BOOL WINAPI SetWaitableTimer(
2   _In_           HANDLE           hTimer,
3   _In_     const LARGE_INTEGER    *pDueTime,
4   _In_           LONG             lPeriod,
5   _In_opt_       PTIMERAPCROUTINE pfnCompletionRoutine,
6   _In_opt_       LPVOID           lpArgToCompletionRoutine,
7   _In_           BOOL             fResume
8 );

  ○ 参数1: hTimer [in]

    CreateWaitableTimer OpenWaitableTimer 返回的一个句柄 

  ○ 参数2:pDueTime [in]

    在100纳秒间隔内,计时器的状态将被设置为信号的时间。使用FILETIME结构描述的格式。正值表示绝对时间。一定要使用基于utc的绝对时间,因为系统在内部使用utc时间。负值表示相对时间。实际计时器的准确性取决于硬件的性能。有关基于utc时间的更多信息,请参阅系统时间。

  ○ 参数3 lPeriod [in]

    计时器的周期,以毫秒为单位。如果lPeriod为零,则计时器将显示一次。如果lPeriod大于0,计时器是周期性的。每当周期结束时,定时计时器会自动重新启动,直到计时器被取消使用CancelWaitableTimer函数或重置使用SetWaitableTimer。如果lPeriod小于0,则函数失败。

  ○ 参数4 pfnCompletionRoutine [in, optional]

    指向可选完成例程的指针。完成例程是PTIMERAPCROUTINE的应用程序定义函数,当计时器被释放时执行。有关计时器回调函数的更多信息,请参见TimerAPCProc。有关APCs和线程池线程的更多信息,请参见备注。

   ○ 参数5 lpArgToCompletionRoutine [in, optional]

    传递到完成程序的结构的指针。

   ○ 参数6 fResume [in]

    如果这个参数是正确的,那么当定时器状态设置为信号时,重新存储一个暂停电源保护模式的系统。否则,系统就无法恢复。如果系统不支持恢复,则调用成功,但是GetLastError返回ERROR_NOT_SUPPORT。

 

 1 #define UNICODE
 2 #include <stdio.h>
 3 #include <windows.h>
 4 
 5 int main()
 6 {
 7     HANDLE hTimer = CreateWaitableTimer(nullptr, TRUE, nullptr);
 8     
 9     //时间建构体
10     SYSTEMTIME st = {0};
11     st.wYear = 2017;    //
12     st.wMonth = 7;        //
13     st.wDay = 4;        //14     
15     //时间转换
16     FILETIME ftLocal;
17     SystemTimeToFileTime(&st,&ftLocal);
18     
19     LARGE_INTEGER liDueTime;
20     liDueTime.QuadPart = -100000000LL;
21     
22     SetWaitableTimer(hTimer, &liDueTime, 1000, nullptr, nullptr, FALSE);
23     if(WaitForSingleObject(hTimer, INFINITE) == WAIT_TIMEOUT)
24         printf("Time out........");
25     return 0;
26 }

 

 1 #define UNICODE
 2 #include <stdio.h>
 3 #include <process.h>
 4 #include <windows.h>
 5 
 6 HANDLE hTimer;
 7 CRITICAL_SECTION gCS;
 8 
 9 unsigned __stdcall ThreadFunc(void* lParam)
10 {
11     while(WaitForSingleObject(hTimer, INFINITE) != WAIT_TIMEOUT)
12     {
13         printf("Time out........\\r\\n");
14         CancelWaitableTimer(hTimer);
15     }
16     return 0;
17 }
18 
19 int main()
20 {
21     InitializeCriticalSection(&gCS);
22     hTimer = CreateWaitableTimer(nullptr, TRUE, nullptr);
23     
24     HANDLE hThread = (HANDLE)_beginthreadex(nullptr, 0, ThreadFunc, (void*)1,  0, nullptr);
25     
26     //时间建构体
27     SYSTEMTIME st = {0};
28     st.wYear = 2017;    //
29     st.wMonth = 7;        //
30     st.wDay = 4;        //31     
32     //时间转换
33     FILETIME ftLocal;
34     SystemTimeToFileTime(&st,&ftLocal);
35     
36     LARGE_INTEGER liDueTime;
37     liDueTime.QuadPart = -1;    //100纳秒
38     
39     SetWaitableTimer(hTimer, &liDueTime, 1000, nullptr, nullptr, FALSE);
40     /*
41     if(WaitForSingleObject(hTimer, INFINITE) == WAIT_TIMEOUT)
42         printf("Time out........");
43     */
44     WaitForSingleObject(hThread,INFINITE);
45     DeleteCriticalSection(&gCS);
46     CloseHandle(hTimer);
47     return 0;
48 }

 

 

 1 #define UNICODE
 2 #include <stdio.h>
 3 #include <process.h>
 4 #include <windows.h>
 5 
 6 HANDLE hTimer;
 7 CRITICAL_SECTION gCS;
 8 
 9 unsigned __stdcall ThreadFunc(void* lParam)
10 {
11     while(WaitForSingleObject(hTimer, INFINITE) != WAIT_TIMEOUT)
12     {
13         EnterCriticalSection(&gCS);
14         printf("Time out........\\r\\n");
15         //if(!CancelWaitableTimer(hTimer))
16         //    printf("Error");
17         LeaveCriticalSection(&gCS);
18     }
19     return 0;
20 }
21 
22 int main()
23 {
24     InitializeCriticalSection(&gCS);
25     hTimer = CreateWaitableTimer(nullptr, FALSE, nullptr);
26     
27     HANDLE hThread = (HANDLE)_beginthreadex(nullptr, 0, ThreadFunc, (void*)1,  0, nullptr);
28     
29     //时间建构体
30     SYSTEMTIME st = {0};
31     st.wYear = 2017;    //
32     st.wMonth = 7;        //
33     st.wDay = 4;        //34     
35     //时间转换
36     FILETIME ftLocal;
37     SystemTimeToFileTime(&st,&ftLocal);
38     
39     LARGE_INTEGER liDueTime;
40     liDueTime.QuadPart = -1;    //100纳秒
41     
42     SetWaitableTimer(hTimer, &liDueTime, 1000, nullptr, nullptr, FALSE);
43     /*
44     if(WaitForSingleObject(hTimer, INFINITE) == WAIT_TIMEOUT)
45         printf("Time out........");
46     */
47     WaitForSingleObject(hThread,INFINITE);
48     DeleteCriticalSection(&gCS);
49     CloseHandle(hTimer);
50     return 0;
51 }

 

 

 

 1 #define UNICODE
 2 #include <stdio.h>
 3 #include <process.h>
 4 #include <windows.h>
 5 
 6 HANDLE hTimer;
 7 CRITICAL_SECTION gCS;
 8 
 9 unsigned __stdcall ThreadFunc(void* lParam)
10 {
11     while(WaitForSingleObject(hTimer, INFINITE) != WAIT_TIMEOUT)
12     {
13         EnterCriticalSection(&gCS);
14         printf("%d Time out........\\r\\n",(int)lParam);
15         //if(!CancelWaitableTimer(hTimer))
16         //    printf("Error");
17         LeaveCriticalSection(&gCS);
18     }
19     return 0;
20 }
21 
22 int main()
23 {
24     InitializeCriticalSection(&gCS);
25     hTimer = CreateWaitableTimer(nullptr, FALSE, nullptr);
26     
27     HANDLE hThread = (HANDLE)_beginthreadex(nullptr, 0, ThreadFunc, (void*)1,  0, nullptr);
28     HANDLE hThread2 = (HANDLE)_beginthreadex(nullptr, 0, ThreadFunc, (void*)2,  0, nullptr);
29     HANDLE hThread3 = (HANDLE)_beginthreadex(nullptr, 0, ThreadFunc, (void*)3,  0, nullptr);
30     HANDLE hThread4 = (HANDLE)_beginthreadex(nullptr, 0, ThreadFunc, (void*)4,  0, nullptr);
31     //时间建构体
32     SYSTEMTIME st = {0};
33     st.wYear = 2017;    //
34     st.wMonth = 7;        //
35     st.wDay = 4;        //36     
37     //时间转换
38     FILETIME ftLocal;
39     SystemTimeToFileTime(&st,&ftLocal);
40     
41     LARGE_INTEGER liDueTime;
42     liDueTime.QuadPart = -1;    //100纳秒
43     
44     SetWaitableTimer(hTimer, &liDueTime, 1000, nullptr, nullptr, FALSE);
45     /*
46     if(WaitForSingleObject(hTimer, INFINITE) == WAIT_TIMEOUT)
47         printf("Time out........");
48     */
49     WaitForSingleObject(hThread,INFINITE);
50     DeleteCriticalSection(&gCS);
51     CloseHandle(hTimer);
52     return 0;
53 }

 

以上是关于016 可等待计时器对象.6的主要内容,如果未能解决你的问题,请参考以下文章

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

可等待定时器(获取系统时间)

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

内核对象进行线程同步

Windows 中的可等待计时器问题(timeSetEvent 和 CreateTimerQueueTimer)

可等待计时器添加APC测试