线程同步 等待定时器 WaitableTimer 内核对象 CreateWaitableTimer
2015-11-06 17:00
633 查看
0、思考
线程a负责发红包,线程b、c负责抢红包,线程a不会主动告诉b要发红包了,那线程b有什么策略?
1、相关api
CreateWaitableTimer SetWaitableTimer CancelWaitableTimer OpenWaitableTimer WaitForSingleObject WaitForMultipleObject CloseHandle GetLocalTime GetSystemTime SystemTimeToFileTime LocalFileTimeToFileTime
2、写在前面
等待定时器:在某个指定的时间触发或每隔一段时间触发一次。
3、api说明
// 创建可等待的定时器(在某个时间或间隔时间发出信号通知的内核对象) // lpTimerAttributes:安全属性。(通常为NULL) // bManualReset:手动重置(true),被触发时正在等待的所有线程变成可调度状态;自动重置(false),被触发时只有一个正在等待该计时器的线程 变成可调度线程。(通常为false) // lpTimerName:内核对象名称。 WINBASEAPI __out_opt HANDLE WINAPI CreateWaitableTimerA( __in_opt LPSECURITY_ATTRIBUTES lpTimerAttributes, __in BOOL bManualReset, __in_opt LPCSTR lpTimerName ); WINBASEAPI __out_opt HANDLE WINAPI CreateWaitableTimerW( __in_opt LPSECURITY_ATTRIBUTES lpTimerAttributes, __in BOOL bManualReset, __in_opt LPCWSTR lpTimerName ); #ifdef UNICODE #define CreateWaitableTimer CreateWaitableTimerW #else #define CreateWaitableTimer CreateWaitableTimerA #endif // !UNICODE // 设置触发定时器 // hTimer:要触发的定时器句柄 // lpDueTime:第一次触发的时间 // lPeriod:间隔多久触发 // pfnCompletionRoutine:(通常为NULL) // lpArgToCompletionRoutine:(通常为NULL) // fResume:用于支持挂起和继续执行的计算机(如果希望计算机处于休眠状态时定时器可以唤醒计算机恢复运行则设置为true)。(通常为false) WINBASEAPI BOOL WINAPI SetWaitableTimer( __in HANDLE hTimer, __in const LARGE_INTEGER *lpDueTime, __in LONG lPeriod, __in_opt PTIMERAPCROUTINE pfnCompletionRoutine, __in_opt LPVOID lpArgToCompletionRoutine, __in BOOL fResume ); // 取出定时器的句柄并将它撤消,定时器不会再进行报时(SetWaitableTier前系统会默认CancelWaitableTimer撤销原报时条件) // hTimer:定时器 WINBASEAPI BOOL WINAPI CancelWaitableTimer( __in HANDLE hTimer ); // 进程可以获得它自己的与进程相关的现有等待定时器的句柄 // dwDesiredAccess:指定想要的访问权限,EVENT_ALL_ACCESS请求对事件对象的完全访问;EVENT_MODIFY_STATE允许使用。(通常为EVENT_ALL_ACCESS) // bInheritHandle:是否希望子进程继承事件对象的句柄。(通常为false) // lpTimerName:要打开的事件对象的名称。 WINBASEAPI __out_opt HANDLE WINAPI OpenWaitableTimerA( __in DWORD dwDesiredAccess, __in BOOL bInheritHandle, __in LPCSTR lpTimerName ); WINBASEAPI __out_opt HANDLE WINAPI OpenWaitableTimerW( __in DWORD dwDesiredAccess, __in BOOL bInheritHandle, __in LPCWSTR lpTimerName ); #ifdef UNICODE #define OpenWaitableTimer OpenWaitableTimerW #else #define OpenWaitableTimer OpenWaitableTimerA #endif // !UNICODE
4、C++封装
#pragma once #include <windows.h> class ncWaitableTimer { public: ncWaitableTimer(BOOL bManualReset = FALSE, LPCTSTR lpTimerName = NULL) { _timer = CreateWaitableTimer(NULL, bManualReset, lpTimerName); } ~ncWaitableTimer() { CloseHandle(_timer); } public: BOOL set(const LARGE_INTEGER* lpDueTime, LONG lPeriod, PTIMERAPCROUTINE pfnCompletionRoutine = NULL, LPVOID lpArgToCompletionRoutine = NULL, BOOL fResume = FALSE) { return SetWaitableTimer(_timer, lpDueTime, lPeriod, pfnCompletionRoutine, lpArgToCompletionRoutine, fResume); } DWORD wait(DWORD timeout = INFINITE) { return WaitForSingleObject (_timer, timeout); } BOOL cancel () { return CancelWaitableTimer(_timer); } private: HANDLE _timer; };
5、顺藤摸瓜
APC:asynchronous procedure call异步任务调用; SetWaitableTimer的pfnCompletionRoutine和lpArgToCompletionRoutine用来支持APC; 如果希望时间一到就让计时器把一个APC添加到队列中,需要定义一个APC函数,并把函数地址pfnCompletionRoutine传进来,原形如下: typedef VOID (APIENTRY *PTIMERAPCROUTINE)( __in_opt LPVOID lpArgToCompletionRoutine, __in DWORD dwTimerLowValue, __in DWORD dwTimerHighValue ); 注意:计时器被触发时当且仅当SetWaitableTimer的调用线程处于可提醒状态。(例如:SleepEx、WaitForSingleObjectEx、WaitForMultipleObjectsEx、SignalObjectAndWait这些进入等待状态) 原因:如果线程并非在其中一个函数内等待,那么系统不会吧计时器的APC函数添加到队列中。 注意:线程不应该在等待一个计时器句柄的同时以可提醒的方式等待同一个计时器。 原因:当计时器被触发时,等待成功,线程被唤醒,这时线程退出可提醒状态,APC函数就不调用了。 注意:WaitForSingleObjectEx实际上会等待计时器两次:一次是可提醒的,另一次是内核对象句柄;当内核对象句柄被触发时,线程也退出可提醒状态; 注意:SleepEx不会等待内核对象句柄,所有线程一直处于可提醒状态,直到APC函数处理完完毕后返回可警告函数(即退出可提醒状态) 注意:APC函数得确保再次被触发之前结束,不然APC函数的加入速度大于处理速度。
鸣谢
相关文章推荐
- Google最新人工智能算法RankBrain的实现--写在后面的话
- aidl详解:同一APK内,不同apk间的activty与service通信
- FastDFS与Raid思考
- DataInputStream FileInputStream 区别
- 8.3.14 Paint几个枚举-常量值以及ShadowLayer阴影效果
- 训练集(train set)、 验证集(validation set) 、测试集(test set)
- 解决U盘在mac air下格式化后在windows上无法显示
- 小议:SharePoint 2010 Upgrade时,Restore Content Database 失败的解决方案?
- SOJ 3711 Mountain Road
- hdu 3264 Open-air shopping malls(求圆相交的面积,二分)
- 解决no cpu/abi system image available for this target的问题
- 谷歌发布自动回复邮件人工智能技术
- tail命令
- 把OnDraw和OnPaint弄清楚(转贴)
- soj 2505: The County Fair(离散化 + 记忆化搜索)
- Handler.obtainMessage()
- 无法真机调试Installation failed with the following output:pkg: /data/local/tmp/Package.apk
- 机器学习
- 函数waitpid和WTERMSIG说明
- 百度大数据+零售发挥引擎优势 ------BDL ,大数据+亚当科茨领导的人工智能实验室和由张潼领导的大数据实验室