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

  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 }

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

时间: 2024-12-18 13:52:28

线程同步——内核对象实现线程同步——可等待计时器内核对象的相关文章

线程同步——内核对象实现线程同步——信号量

1 /* 2 3 信号量内核对象 4 信号量与其它内核量相同,包含一个使用计数,除此之外还包含两个量. 5 一个最大资源计数和一个当前资源计数. 6 信号量规则如下: 7 如果当前资源计数大于0,那么信号量处于触发状态. 8 如果当前资源计数等于0,那么信号量处于未触发状态. 9 系统绝不会让当前资源计数变为负数. 10 当前资源计数绝不会大于最大资源计数. 11 12 下面我们看一下信号量的创建函数 13 HANDLE CreateSemaphore( 14 LPSECURITY_ATTRIB

线程同步——内核对象实现线程同步——事件内核对象

1 事件内核对象 2 3 事件类型对象有两种不同类型,手动重置和自动重置 4 手动重置:当一个手动重置对象被触发时候,等待该对象的所有线程变为可调度. 5 自动重置:当一个自动重置对象被触发时,只有一个等待该事件的线程会变为可调度 6 7 下面是一个创建事件内核对象的函数: 8 HANDLE CreateEvent( 9 LPSECURITY_ATTRIBUTES lpEventAttributes, 10 BOOL bManualReset, 11 BOOL bInitialState, 12

线程同步——内核对象实现线程同步——等待函数

1 对于内核对象实现线程同步,不得不提三点: 2 1)大多数内核对象既有触发也有未触发两个状态 3 比如:进程.线程.作业.文件流.事件.可等待的计时器.信号量.互斥量 4 2)等待函数:等待函数使线程自愿进入等待状态,直到指定的内核对象变为触发状态为止, 5 说道等待我们最喜欢不过了,因为这样不会浪费我们宝贵的CPU时间. 6 3)对于自动重置对象来说,当对象被触发时,函数会自动检测到(手动重置对象为触发是,函数也能检测到), 7 并开始执行,但是在函数会在返回之前使事件变为非触发状态. 8

第9章 用内核对象进行线程同步(4)_死锁(DeadLock)及其他

9.7 线程同步对象速查表 对象 何时处于未触发状态 何时处于触发状态 成功等待的副作用 进程 进程仍在运行的时候 进程终止的时(ExitProcess.TerminateProcess) 没有 线程 线程仍在运行的时候 线程终止的时候(ExitThread.TermimateThread) 没有 作业 作业尚未超时的时候 作业超时的时候 没有 文件 有待处理的I/O请求的时候 I/O请求完成的时候 没有 控制台输入 没有输入的时候 有输入的时候 没有 文件变更通知 文件没有变更的时候 文件系统

第9章 用内核对象进行线程同步(2)_可等待计时器(WaitableTimer)

9.4 可等待的计时器内核对象——某个指定的时间或每隔一段时间触发一次 (1)创建可等待计时器:CreateWaitableTimer(使用时应把常量_WIN32_WINNT定义为0x0400) 参数 描述 psa 安全属性(如使用计数.句柄继承等) bManualReset 手动重置计时器还是自动重置计时器. ①当手动计时器被触发,所有正在等待计时器的线程都变可为可调度. ②当自动计时器被触发时,只有一个正在等待计数器的线程变为可调度 pszName 对象的名字 (2)也可以打开一个己经存在的

第9章 用内核对象进行线程同步(3)_信号量(semaphore)、互斥量(mutex)

9.5 信号量内核对象(Semaphore) (1)信号量的组成 ①计数器:该内核对象被使用的次数 ②最大资源数量:标识信号量可以控制的最大资源数量(带符号的32位) ③当前资源数量:标识当前可用资源的数量(带符号的32位) (2)信号量的使用规则 ①如果当前资源计数>0,那么信号量处于触发状态,表示有可用资源. ②如果当前资源计数=0,那么信号量处于未触发状态,表示没有可用资源. ③系统绝不会让当前资源计数变为负数: ④当前资源计数绝对不会大于最大资源计数 (3)信号量的用法 (4)相关函数

内核对象进行线程同步

前言: 具体的可等待的内核对象有: 进程,线程,作业,文件以及控制台的标准输入流/输出流/错误流,事件,可等待的计时器,信号量,互斥量. 等待函数: DWORD WaitForSingleObject( HANDLE hObject,//用来标识要等待的内核对象 DWORD dwMilliseconds);//等待的时间 DWORD WaitForMultipleObjects( DWORD dwCount,//函数检查的内核对象的数量(最大为MAXIMUM_WAIT_OBJECTS) CONS

Windows 互斥对象在线程同步上的运用

互斥对象在线程同步时的使用 1 多线程在资源共享的时候出现的问题 在程序中如果不同线程对同一个对象进行操作的话就有可能出现因为线程切换而导致的问题.例如下面的程序 #include <stdio.h> #include <WinSock2.h> #include <iostream> using namespace std; #pragma comment(lib,"ws2_32.lib") DWORD WINAPIfun1Proc(LPVOID l

线程同步——用户模式下线程同步——Interlocked实现线程同步

1 线程同步分为用户模式下的线程同步和内核对象的线程同步. 2 3 当然用户模式下的线程同步实现速度比内核模式下快,但是功能也有局 4 5 6 7 8 //1.利用原子访问: Interlocked系列函数,关于Interlocked系列函数,我需要知道的是他们,执行的极快 9 10 //(1)首先是InterlockedExchangeAdd兄弟函数, 11 //第一个参数 Addend 代表进行操作数的地址, 12 //第二个参数 Value 代表增加的值,如果是想进行减法,传负数即可 13