wxWidgets第十四课 wxTimer定时器

简介:

说明

    OnIdle CPU空闲的情况下处理消息,如果需要定时功能,就需要使用定时器wxTimer 


问题

    比如定时器函数运行耗时10秒,定时的时间是10毫秒,是否是每隔10毫秒执行一次定时器函数,还是等待定时器函数运行结束,才开始重新计时


结果

    在定时器函数中执行::Sleep(10000);等待10秒,发现实际上需要等待定时器函数执行结束,才开始重新计时。所以在如下的场景需要特别小心:需要定时读取数据,而读取数据之后,执行一大堆耗时的操作,这个时候,就需要启动线程去处理,而不能在定时器函数中完成


例子

#include "wx/timer.h"


private:

wxTimer *m_timer;


//指定定时器的ID

#define TIMER_ID 1000

//将定时器ID和定时执行函数关联起来

EVT_TIMER(TIMER_ID, CFlightInstrumentPanel::OnTimer)


//创建定时器,指定定时器ID使用哪个定时器

m_timer = new wxTimer(this, TIMER_ID);

//启动定时器,参数是定时的时间间隔

m_timer->Start(1000);


编写定时器的执行内容

void CFlightInstrumentPanel::OnTimer( wxTimerEvent& event )

{

static int x = 0;

if (x<1000)

{

wxClientDC dc(this);

wxPen pen(*wxRED,1);

dc.SetPen(pen);

dc.DrawRectangle(x, 0, 200, 300);

dc.SetPen(wxNullPen);

x=x+100;

}

}


停止定时器

m_timer->Stop();


注意

定时器是一种资源,类似文件句柄,不可能无限的创建,定时结束之后,最后停止定时器,释放资源,并且如果在关闭窗口之前没有停止定时器,会出现


0xC0000005: 读取位置 0xFEEEFF06 时发生访问冲突错误,相关的内容查看其它的文章





定时器SetTimer的效率分析场景分析

    项目中使用wxWidgets框架,其中应用了该框架的定时器wxTimer,频繁进行了开启和关闭。在嵌入式操作系统中,性能是重中之重因此想尝试分析当前这种应用场景,是否会消耗CPU和内存的资源,跟踪wxWidgets的源码,发现定时器在windows系统下调用了使用了SetTimer和KillTimer函数进行定时器的启动和销毁。


疑惑

第一点:启动定时器是否是启动一条线程,然后Sleep等待时间的触发

第二点:频繁启动定时器,然后关闭,是否需消耗大量的资源

如果第一条成立的话,线程的创建以及切换都是非常

可观的开销


解惑

第一点:启动定时器SetTimer不是启动一个线程。该函数主要将新的

定时器结构加入内核的全局变量gptmrFirst这个链表,使用

KillTimer移除该定时器的结构体。系统会定时遍历该链表,

一旦定时时间就绪,就会向程序发送WM_TIMER消息,应用程序

接收到消息,开始处理逻辑

第二点:启动和关闭定时器也只是添加或者移除结构体,效率应该是

比较高的。创建线程的开销以及占用的堆栈都是可观的,尽管

可以设置线程堆栈的大小



前提

当前没有搜索到windows定时器的源码


参考:http://bbs.csdn.net/topics/360222963


基于以下的论断:

win32k中有一个全局变量gptmrFirst,里面存放了第一个定时器结构的指针,定时器结构以链表的形式储存

线程在消息循环中会调用GetMessageW->NtUserGetMessage->xxxInternalGetMessage->xxxRealInternalGetMessage

xxxRealInternalGetMessage后面会调用DoTimer,DoTimer就遍历整个定时器链表,并比较每个Timer的Win32Thread指针是不是于win32k的


全局变量gptiCurrent,gptiCurrent中保存的是当前线程的Win32Thread结构的指针(许多win32k函数开头都会有EnterCrit,这里面就设


置gptiCurrent为PsGetThreadWin32Thread的返回值)

如果是,表明这个Timer属于当前线程,所以就检查Timer是否已就绪(到时),如果就绪,则调用StoreQMessage放置一个WM_TIMER或


WM_SYSTIMER消息,后面xxxRealInternalGetMessage会将其取回


csrss.exe进程有一个叫raw input thread的内核线程,其内核对象地址的地址放在win32k全局变量gptiRit中

这个线程负责处理键盘输入,鼠标输入等,当然也有定时器,它会使用KeWaitForMultipleObjects等待一组内核对象,其中就有主定时


器,如果主定时器到时,就执行TimerProc

TimerProc函数会遍历gptmrFirst链表,减少每个定时器的剩余时间,并把到期的定时器设置为已就绪



     本文转自fengyuzaitu 51CTO博客,原文链接:http://blog.51cto.com/fengyuzaitu/1955425,如需转载请自行联系原作者




相关文章
|
6月前
|
API 开发工具 C++
游戏编程之十五 DirectDraw 的基本知识
游戏编程之十五 DirectDraw 的基本知识
80 0
|
7月前
|
Linux
手把手教你写Linux设备驱动---定时器(一)(基于友善之臂4412开发板)
手把手教你写Linux设备驱动---定时器(一)(基于友善之臂4412开发板)
85 0
|
11月前
|
UED
刘金玉的零基础VB教程071期:贪吃蛇游戏开发第七节 游戏暂停控制
刘金玉的零基础VB教程071期:贪吃蛇游戏开发第七节 游戏暂停控制
|
11月前
刘金玉的零基础VB教程070期:贪吃蛇游戏开发第六节 记分与故障排除
刘金玉的零基础VB教程070期:贪吃蛇游戏开发第六节 记分与故障排除
|
12月前
自制的MATLAB拼图游戏GUI界面版详解(下篇)
自制的MATLAB拼图游戏GUI界面版详解(下篇)
117 0
蓝桥杯之单片机学习(二十四)——自写模板库
蓝桥杯之单片机学习(二十四)——自写模板库
101 0
|
C语言 C++ 开发者
三子棋小游戏及如何让朋友也能玩自己写的游戏(程序)(exe如何附带动态链接库dll)C语言从入门到入土(入门特别篇)(四)
一:三子棋 1.游戏的基本开始流程() 2.三子棋的实现 2.1第一步写出基本流程 2.2第二步打印菜单 2.3游戏的实现 2.3.1初始化棋盘 2.3.2打印棋盘 2.3.3玩家下棋 2.3.4电脑下棋 2.3.5判断 2.4游戏的整个代码 game.c: 2.5三子棋的扩展 二:vs如何发布exe文件并附带动态链接库 第一步:vs->工具->命令行->开发者 PowerShell(P) 第二步:查看vs 是Debug还是Releas 是x86还是x64 第三步:找到exe所在位置 第四步:查询你exe文件所需要的的动态链接库(dll)
三子棋小游戏及如何让朋友也能玩自己写的游戏(程序)(exe如何附带动态链接库dll)C语言从入门到入土(入门特别篇)(四)
|
C语言 C++ 开发者
三子棋小游戏及如何让朋友也能玩自己写的游戏(程序)(exe如何附带动态链接库dll)C语言从入门到入土(入门特别篇)(二)
一:三子棋 1.游戏的基本开始流程() 2.三子棋的实现 2.1第一步写出基本流程 2.2第二步打印菜单 2.3游戏的实现 2.3.1初始化棋盘 2.3.2打印棋盘 2.3.3玩家下棋 2.3.4电脑下棋 2.3.5判断 2.4游戏的整个代码 game.c: 2.5三子棋的扩展 二:vs如何发布exe文件并附带动态链接库 第一步:vs->工具->命令行->开发者 PowerShell(P) 第二步:查看vs 是Debug还是Releas 是x86还是x64 第三步:找到exe所在位置 第四步:查询你exe文件所需要的的动态链接库(dll)
三子棋小游戏及如何让朋友也能玩自己写的游戏(程序)(exe如何附带动态链接库dll)C语言从入门到入土(入门特别篇)(二)
|
C语言 C++ 开发者
三子棋小游戏及如何让朋友也能玩自己写的游戏(程序)(exe如何附带动态链接库dll)C语言从入门到入土(入门特别篇)(三)
一:三子棋 1.游戏的基本开始流程() 2.三子棋的实现 2.1第一步写出基本流程 2.2第二步打印菜单 2.3游戏的实现 2.3.1初始化棋盘 2.3.2打印棋盘 2.3.3玩家下棋 2.3.4电脑下棋 2.3.5判断 2.4游戏的整个代码 game.c: 2.5三子棋的扩展 二:vs如何发布exe文件并附带动态链接库 第一步:vs->工具->命令行->开发者 PowerShell(P) 第二步:查看vs 是Debug还是Releas 是x86还是x64 第三步:找到exe所在位置 第四步:查询你exe文件所需要的的动态链接库(dll)
|
C语言 C++ 开发者
三子棋小游戏及如何让朋友也能玩自己写的游戏(程序)(exe如何附带动态链接库dll)C语言从入门到入土(入门特别篇)(一)
一:三子棋 1.游戏的基本开始流程() 2.三子棋的实现 2.1第一步写出基本流程 2.2第二步打印菜单 2.3游戏的实现 2.3.1初始化棋盘 2.3.2打印棋盘 2.3.3玩家下棋 2.3.4电脑下棋 2.3.5判断 2.4游戏的整个代码 game.c: 2.5三子棋的扩展 二:vs如何发布exe文件并附带动态链接库 第一步:vs->工具->命令行->开发者 PowerShell(P) 第二步:查看vs 是Debug还是Releas 是x86还是x64 第三步:找到exe所在位置 第四步:查询你exe文件所需要的的动态链接库(dll)
三子棋小游戏及如何让朋友也能玩自己写的游戏(程序)(exe如何附带动态链接库dll)C语言从入门到入土(入门特别篇)(一)