windows定时器编程
目前,Windows下的定时器编程主要有三种方式。
1)SetTimer定时器是利用Windows窗口消息WM_TIMER来实现的。使用方法非常简单,SetTimer创建定时器,KillTimer销毁定时器。使用条件是调用线程必须要有窗口消息队列message queue,因此如果是工作线程就无法使用这种方法。
2)WaitableTimer定时器,其实应该算是一种线程同步对象,CreateWaitableTimer创建定时器对象,SetWaitableTimer设置定时器回调函数,CLoseHandle销毁定时器。WaitableTimer可以跨线程、进程使用,只要知道定时器对象名字(创建定时器时设置)就可以控制该定时器对象了。WaitableTimer定时器的回调函数实际上是一个APC(Asynchronous Procedure Calls)异步过程调用函数。
关于APC方面的知识可参考“谈谈对APC的一点理解”一文http://blog.csdn.net/wwwwly/archive/2009/07/10/4337907.aspx
3)TimerQueueTimer定时器,应该算迄今为止Windows系统最强大的定时器了。他可以支持多种工作模式,而且定时精度也是最高的。
使用时,首先要调用CreateTimerQueue创建一个定时器队列,然后用CreateTimerQueueTimer来创建一个TimerQueueTimer定时器,
WT_EXECUTEDEFAULT,默认设置,回调函数将进入一个非I/O工作线程队列WT_EXECUTEINTIMERTHREAD,回调函数作为APC,在定时器线程中被调用,被调用的条件是线程进入可警告等待状态alertable wait status。仅适用于短时任务,否则可能会影响队列中的其他定时器。
WT_EXECUTEINIOTHREAD,回调函数进入一个I/O工作线程队列,请注意,大多数定时器都需要调用线程进入可警告等待状态alertable wait status,并不是随随便便就能发生定时调用的。一个线程是否进入可警告等待状态可参见微软的说明http://msdn.microsoft.com/en-us/library/ms686307.aspx
A thread goes into an alertable wait state by calling either SleepEx, MsgWaitForMultipleObjectsEx, WaitForSingleObjectEx, or WaitForMultipleObjectsEx, with the function's bAlertable parameter set to TRUE.
所以希望定时器不受这种可警告等待状态的影响,最好是用TimerQueue来完成。
等待定时器与用户定时器的区别
1、等待定时器(SetWaitableTimer)与用户定时器(SetTimer)它们之间的最大差别是,用户定时器需要在应用程序中设置许多附加的用户界面结构,这使定时器变得资源更加密集。
2、等待定时器属于内核对象,这意味着它们可以供多个线程共享,并且是安全的。
用户定时器:用户定时器能够生成WM_TIMER消息,这些消息将返回给调用SetTimer(用于回调定时器)的线程和创建窗口(用于基于窗口的定时器)的线程。因此,当用户定时器报时的时候,只有一个线程得到通知。
等待定时器:多个线程可以在等待定时器上进行等待,如果定时器是个人工重置的定时器,则可以调度若干个线程。
如果要执行与用户界面相关的事件,以便对定时器作出响应,那么使用用户定时器来组织代码结构可能更加容易些,因为使用等待定时器时,线程必须既要等待各种消息,又要等待内核对象(如果要改变代码的结构,可以使用MsgaitForMultipleObjects函数)。
等待定时器,当到了规定时间的时候,更有可能得到通知。WM_TIMER消息始终属于最低优先级的消息,当线程的队列中没有其他消息时,才检索该消息。等待定时器的处理方法与其他内核对象没有什么差别(PS:因此其使用与内核对象的使用一个样,这就是所谓的触类旁通吧),如果定时器发出报时信息,而你的线程正在等待之中,那么你的线程就会醒来。
一个windows编程示例
#include <iostream>
#include <windows.h>
#include <stdio.h> using namespace std; static int COUNT = ; VOID CALLBACK TimerRoutine(PVOID lpParameter, BOOLEAN TimerOrWaitFired)
{
if (NULL == lpParameter)
{
cout << "TimerRoutine parameter is NULL!" << endl;
return;
} printf("the values of param is :%d\n", *(int*)lpParameter);
} int main(int argc, TCHAR *argv[])
{
HANDLE m_hTimerQueueTimer = NULL;
HANDLE m_hTimerQueue = NULL; while (NULL == (m_hTimerQueue = CreateTimerQueue())) {
cout << "Create timer queue failed!" << endl;
Sleep();
} while (!CreateTimerQueueTimer(&m_hTimerQueueTimer, m_hTimerQueue, WAITORTIMERCALLBACK(TimerRoutine), &COUNT, , , NULL))
{
cout << "Create timer failed!" << endl;
Sleep();
} while () {
Sleep();
COUNT++;
} if (m_hTimerQueueTimer != NULL)
DeleteTimerQueueTimer(m_hTimerQueue, m_hTimerQueueTimer, INVALID_HANDLE_VALUE);
if (m_hTimerQueue != NULL)
DeleteTimerQueueEx(m_hTimerQueue, INVALID_HANDLE_VALUE); m_hTimerQueueTimer = NULL;
m_hTimerQueue = NULL; return ;
}
参考:
windows定时器编程的更多相关文章
- windows核心编程 - 线程同步机制
线程同步机制 常用的线程同步机制有很多种,主要分为用户模式和内核对象两类:其中 用户模式包括:原子操作.关键代码段 内核对象包括:时间内核对象(Event).等待定时器内核对象(WaitableTim ...
- (转)Windows驱动编程基础教程
版权声明 本书是免费电子书. 作者保留一切权利.但在保证本书完整性(包括版权声明.前言.正文内容.后记.以及作者的信息),并不增删.改变其中任何文字内容的前提下,欢迎任何读者 以任何形式(包括 ...
- Windows游戏编程之从零开始d
Windows游戏编程之从零开始d I'm back~~恩,几个月不见,大家还好吗? 这段时间真的好多童鞋在博客里留言说或者发邮件说浅墨你回来继续更新博客吧. woxiangnifrr童鞋说每天都在来 ...
- 《Windows核心编程》读书笔记 上
[C++]<Windows核心编程>读书笔记 这篇笔记是我在读<Windows核心编程>第5版时做的记录和总结(部分章节是第4版的书),没有摘抄原句,包含了很多我个人的思考和对 ...
- 【Windows】windows核心编程整理(上)
小续 这是我11年看<windows核心编程>时所作的一些笔记,现整理出来共享给大家 windows核心编程整理(上) windows核心编程整理(下) 线程的基础知识 进程是不活泼的,进 ...
- Windows下编程--模拟时钟的实现
windows下编程--模拟时钟的实现: 主要可以分为几个步骤: (1) 编写按键事件处理(启动和停止时钟) (2) 编写时钟事件处理,调用显示时钟函数 (3) 编写显示时钟函数,要调用显 ...
- C++Windows核心编程读书笔记
转自:http://www.makaidong.com/%E5%8D%9A%E5%AE%A2%E5%9B%AD%E6%96%87/71405.shtml "C++Windows核心编程读书笔 ...
- 【转】《windows核心编程》读书笔记
这篇笔记是我在读<Windows核心编程>第5版时做的记录和总结(部分章节是第4版的书),没有摘抄原句,包含了很多我个人的思考和对实现的推断,因此不少条款和Windows实际机制可能有出入 ...
- windows多线程编程星球(一)
以前在学校的时候,多线程这一部分是属于那种充满好奇但是又感觉很难掌握的部分.原因嘛我觉得是这玩意儿和编程语言无关,主要和操作系统的有关,所以这部分内容主要出现在讲原理的操作系统书的某一章,看完原理是懂 ...
随机推荐
- java基础 static
参考文章: 静态导包:https://blog.csdn.net/u012338954/article/details/51010337 常量池:http://blog.sina.com.cn/s/b ...
- [C++基础] 变量、关键字、运算符、位操作篇
一.变量篇 1 全局变量和静态变量有什么异同? 相同:都在静态存储区分配空间,生命周期与程序生命周期相同. 区别:全局变量的作用域是整个程序,它只需要在一个源文件中定义,就可以作用于所有的源文件.而静 ...
- nginx负载均衡+keepalived高可用
nginx负载均衡+keepalived高可用 环境准备 192.168.88.111:nginx + keepalived MASTER 192.168.88.112:nginx + keepa ...
- C语言学习系列笔记
1.小甲鱼 C语言教程系列
- Pycharm 个人认为舒服漂亮又好用的主题风格
又开始和code打交道了系列…… 实验室换了新电脑,故而,重新安装了各种软件,乃至重新配置 Pycharm主题,找了好久,终于找到,想着应该mark一下,以备下次需要. 个人认为 Monokai 这 ...
- python入门之名称空间的查找顺序
名称空间的查找顺序: 局部:局部 > 全局 > 内置 全局:全局 > 内置 # 内置再找不到就报错 # 函数内部使用的名字,在定义阶段已经规定死了,与你的调用位置无关 x = 111 ...
- .net core 在 View 中使用 Jquery 无效问题
问题描述: 在 View 视图中使用模板 _Layout.cshtml,其中模板已经调用了 Jquery.js ,但是在 View 视图下写 js 无效.后来通过浏览器查看自己写的 js 压根没加载出 ...
- 分享一个Linux C++消息通信框架TCPSHM
由于本人从事行业关系,Linux环境下的低延迟通信是我关注的技术之一.要达到极端的低延迟,当然同机器内IPC比网络通信快,而Linux IPC方式中无疑是共享内存延迟最低.不过相对于TCP这种通用的通 ...
- myeclipse导入项目中文乱码怎么解决教程
大家在Myeclipse导入项目的时候,应该都遇见过一些乱码的问题,不单单只是Myeclipse有这个问题,那么怎么解决Myeclipse导入项目乱码的问题呢,问题出现的原因是什么呢,下面来看看答案. ...
- Python协程介绍(转)
原文:https://www.liaoxuefeng.com/wiki/897692888725344/923057403198272 协程,又称微线程,纤程.英文名Coroutine. 协程的概念很 ...