• 线程同步——内核对象实现线程同步——可等待计时器内核对象


      1 可等待计时器
      2     可等待计时器是这样一种内核对象,他们会在某个指定的时间触发或每隔一段时间触发一次。
      5     下面我们来介绍一下创建可等待计时器函数:
      6 
      7     HANDLE CreateWaitableTimer( 
      8     LPSECURITY_ATTRIBUTES lpTimerAttributes, 
      9     BOOL bManualReset, 
     10     LPCSTR lpTimerName );
     11 第一、三个参数我想我也不用介绍了哈,这是创建内核对象基本都会有的参数。
     12     第二个参数bManualReset表示是创建一个手动重置(TRUE),还是自动重置(FALSE)计时器。
     13     有一点需要记住:创建可等待计时器总是处于未触发状态。必须调用SetWaitableTimer函数来告诉它。
     14 
     15     BOOL SetWaitableTimer(
     16     HANDLE hTimer, 
     17     const LARGE_INTEGER *lpDueTime,
     18     LONG lPeriod, 
     19     PTIMERAPCROUTINE pfnCompletionRoutine,
     20     LPVOID lpArgToCompletionRoutine,
     21     BOOL fResume );
     22 第一参数hTimer表示我们要设置的计时器
     23     第二个和第三个参数应该一起使用,lpDueTime表示第一次触发应该在什么时候,
     24     lPeriod表示计时器应该以什么样的频度触发。第三个参数的单位是微秒
     25     另外两个参数这里就先不介绍了,如果感兴趣可以阅读《windows核心编程(第五版)》245页 或者参考MSDN.
     26     如果只是简单的应用,后面三个参数,依次填入 NULL,NULL,FALSE 即可,嘿嘿,简单吧!
     27 
     28 
     29 特别注意:
     30 如果该计时器是手动重置,则正在等待该线程的所有线程变为可调度,当该定时器是自动重置,
     31 则只有一个等待该线程的计时器变为可调度。当定时器是自动重置时,每当WaitFor*Object 
     32 获得该对象时,会重新计时,而手动重置则不会重新计时,这点特别注意。
     33 
     34 下面说一下使用步骤
     35 1)
     36 //定义一个定时器内核对象,还有一些关于时间的变量
     37 HANDLE g_hTimer ;  
     38 SYSTEMTIME st;
     39 
     40 FILETIME ftLocal,ftUTC;
     41 
     42 LARGE_INTEGER liUTC ;
     43 2 44 //创建一个自动重置的定时器内核对象
     45 g_hTimer = CreateWaitableTimer(NULL,FALSE,NULL);
     46 
     47 3)设置定时器内核对象,时间可以更根据自己的实际情况设定
     48 //第一次响应是在 2014.08.10  在 17:12分
     49 
     50 st.wYear = 2014 ;
     51 st.wMonth = 8 ;
     52 //st.wDayOfWeek = 0  //可以忽悠  
     53 st.wDay = 10 ;
     54 st.wHour = 17 ;
     55 st.wMinute = 12;
     56 st.wSecond = 0 ;
     57 st.wMilliseconds = 0 ;
     58 
     59 SystemTimeToFileTime(&st,&ftLocal);
     60 
     61 LocalFileTimeToFileTime(&ftLocal,&ftUTC) ;
     62 
     63 liUTC.LowPart = ftUTC.dwLowDateTime ;
     64 liUTC.HighPart = ftUTC.dwHighDateTime ;
     65 
     66 //每隔1秒钟响应依次,记住,第三个单位是微妙,这里容易使人忘记。
     67 SetWaitableTimer(g_hTimer,&liUTC,1000,NULL,NULL,FALSE);
     68 
     69 4)在线程函数中调用
     70 DWORD WINAPI ThreadFunOne(PVOID pvParam) 
     71 {
     72     while(1)
     73     {
     74         WaitForSingleObject(g_hTimer,INFINITE);
     75         g_x++;
     76         cout<<"我是ThreadFunOne:"<<g_x<<endl;
     77     }
     78     return 0;
     79 }
     80 
     81 
     82 
     83 #include "windows.h"
     84 #include "iostream"
     85 using namespace std;
     86 long g_x = 0 ;
     87 
     88 //定义一个定时器内核对象,还有一些关于时间的变量
     89 HANDLE g_hTimer ;  
     90 SYSTEMTIME st;
     91 
     92 FILETIME ftLocal,ftUTC;
     93 
     94 LARGE_INTEGER liUTC ;
     95 
     96 //定义线程函数1
     97 DWORD WINAPI ThreadFunOne(PVOID pvParam) ;
     98 
     99 //定义线程函数2
    100 DWORD WINAPI ThreadFunTwo(PVOID pvParam);
    101 
    102 int main()
    103 {
    104 
    105     //创建一个自动重置的定时器内核对象
    106     g_hTimer = CreateWaitableTimer(NULL,FALSE,NULL);
    107 
    108     //第一次响应是在 2014.08.10  在 17:12分
    109 
    110     st.wYear = 2014 ;
    111     st.wMonth = 8 ;
    112     //st.wDayOfWeek = 
    113     st.wDay = 10 ;
    114     st.wHour = 17 ;
    115     st.wMinute = 12;
    116     st.wSecond = 0 ;
    117     st.wMilliseconds = 0 ;
    118 
    119     SystemTimeToFileTime(&st,&ftLocal);
    120 
    121     LocalFileTimeToFileTime(&ftLocal,&ftUTC) ;
    122 
    123     liUTC.LowPart = ftUTC.dwLowDateTime ;
    124     liUTC.HighPart = ftUTC.dwHighDateTime ;
    125 
    126     SetWaitableTimer(g_hTimer,&liUTC,1000,NULL,NULL,FALSE);
    127 
    128     //创建线程1
    129     HANDLE hThreadOne = CreateThread(NULL,0,ThreadFunOne,0,0,NULL);
    130     CloseHandle(hThreadOne);
    131 
    132     //创建线程2
    133     HANDLE hThreadTwo = CreateThread(NULL,0,ThreadFunTwo,0,0,NULL);
    134     CloseHandle(hThreadTwo);
    135 
    136     //让主线程先挂起,确保其它线程执行完成
    137 
    138     getchar();
    139     cout<<g_x<<endl;
    140     return 0 ;
    141 }
    142 
    143 DWORD WINAPI ThreadFunOne(PVOID pvParam) 
    144 {
    145     while(1)
    146     {
    147         WaitForSingleObject(g_hTimer,INFINITE);
    148         g_x++;
    149         cout<<"我是ThreadFunOne:"<<g_x<<endl;
    150     }
    151     return 0;
    152 }
    153 
    154 DWORD WINAPI ThreadFunTwo(PVOID pvParam)
    155 {
    156     while (1)
    157     {
    158         WaitForSingleObject(g_hTimer,INFINITE);
    159         g_x++;    
    160         cout<<"我是ThreadFunTwo:"<<g_x<<endl;
    161     }
    162     return 0;
    163 }

     

  • 相关阅读:
    幂等设计
    Dubbo
    Kubernetes-K8S
    Log4Net配置以及使用
    网站对话框开源脚本--ArtDialog V6.0
    实现VS2010整合NUnit进行单元测试(转载)
    HTML+CSS页面滚动效果处理
    Bootstrap 表格 笔记
    Bootstrap 排版 笔记
    Bootstrap简介
  • 原文地址:https://www.cnblogs.com/yfyzy/p/3916200.html
Copyright © 2020-2023  润新知