-
2019-08-31 20:05:25
一、前言
此历程来自机器人控制工程中的一部分,“开线程调用多媒体定时器”在工程中是很常用的一部分,但对于新手来说却很难理解。下面小白用最简单的方式,清晰的记录下程序顺序运行的每一环节。
主要完成两件事:声明一个线程,声明一个多媒体定时器。我想你也猜到要怎么做了,对,在声明的线程里面声明多媒体定时器,然后执行。道理是不是很简单,理解这句话你就掌握80%了,程序编写更简单。
二、技术实现
整个程序程序分成四个部分:
- OnBnClickedRbfcontrol()函数,负责声明一个线程,然后执行声明的RBFThreadproc()函数;
- RBFThreadproc(LPVOID pParam)函数,是开启线程后的执行函数,本例程执行多媒体定时器CreateTimer()函数;
- CreateTimer()函数,用来声明一个多媒体定时器,然后执行循环调用函数TimeProc()函数;
- TimeProc()函数,负责循环调用你期望的执行指令。
void CANNControlDlg::OnBnClickedRbfcontrol() { //声明一个线程 HANDLE hThread; UINT uiThreadId = 0; hThread = (HANDLE)_beginthreadex(NULL,0,RBFThreadproc,this,CREATE_SUSPENDED,&uiThreadId); //判断是否声明成功 if(NULL != hThread) { ResumeThread( hThread ); m_RBFThread = hThread; } } UINT CANNControlDlg::RBFThreadproc(LPVOID pParam) { //线程执行内容 CANNControlDlg* pThis = reinterpret_cast<CANNControlDlg*>(pParam); _ASSERTE( pThis!= NULL); pThis->CreateTimer(); return 1L; } UINT CANNControlDlg::CreateTimer() { //声明一个多媒体定时器 timeBeginPeriod(1); FileTimerID = timeSetEvent(DataPeriod,1,TimeProc,(DWORD)this,TIME_PERIODIC); return FileTimerID; } void CALLBACK CANNControlDlg::TimeProc(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2) { //多媒体定时器执行内容 CANNControlDlg* pdcpackerdlg = (CANNControlDlg*)dwUser; pdcpackerdlg->MultiMediaRun(); } void CANNControlDlg::MultiMediaRun() { //多媒体定时器执行函数 ReadDataFromTC(); }
最后,在MultiMediaRun()函数中,编写希望循环执行的代码段。
更多相关内容 -
MFC高精度定时器,多媒体定时器,VS2019,C++
2022-01-25 19:35:16vs2019 MFC 多媒体定时器 ms级定时器 -
多媒体定时器
2016-08-04 16:06:02多媒体定时器 -
多媒体定时器使用范例小例子
2019-07-03 22:06:06这个例子使用了多媒体定时器,并且在界面上面显示多媒体定时器和普通定时器的效果对比,最后显示在毫秒级别的任务,多媒体定时器任务比普通定时器精度更高; -
C#调用多媒体定时器
2016-06-25 18:19:13C#调用采用C++/CLR封装的多媒体定时器的例子及封装库文件。可用Winform和WPF程序中。经过测试可用。 -
widows 高精度多媒体定时器
2018-02-22 17:00:37windows 高精度多媒体定时器,支持毫秒精确定时 -
.net下的多媒体定时器
2014-09-07 17:02:33.Net多媒体定时器使用代码MmTimerNet 可以用于Winform和WPF软件。 需要.net 4.0运行时的支持。 -
linux下多定时器+线程池的实现(经典)
2013-01-11 20:45:58// i)首先在初始化多定时器(init_mul_timer)时利用setitimer注册一个基本的时间单位(如1s)的定时事件; // // ii)用户需要set_a_timer注册自定义定时器时,在timer_manage管理结构中记录这个定时器的回调函数... -
多定时器复用一个硬件定时器
2018-11-23 13:14:56多个定时器复用一个硬件定时器,便于实际开发使用,占用资源少! -
C#版本多媒体定时器
2011-12-01 09:31:02MmTimer 是一个多媒体定时器的C#简单封装。 使用这个定时器,你可以得到1ms精度的单次延时或周期定时。最初是想用来做播放midi文件的时钟,当然你也可以用它来做任何它能做到的事情。 -
C++自定义定时器实现(多对象多定时器)
2012-12-17 18:31:332012.12.17更新,前一个版本在实际测试的时候出现了bug,现在已经改正! -
VC6.0多媒体定时器(多个)
2012-03-09 20:03:02使用VC6.0开发的高精度多媒体定时器,这里创建了多个定时器。并控制对话框资源。 -
高精度多媒体定时器
2015-12-30 15:36:53比Timer定时器的精度更高的定时器,做实时控制经常使用的控制器 -
多媒体定时器VS2010
2015-07-02 09:01:38最基本的多媒体定时器代码,以及基本的测试代码。 -
linux多定时器多线程
2018-12-07 22:52:38Linux中通过多线程多定时器来完成不同的任务;Linux中通过多线程多定时器来完成不同的任务; -
win32多媒体定时器
2022-04-05 14:43:17win32多媒体定时器 几个拉跨的定时器精度 select选择模型:15ms Sleep(1) :15ms timeGetTime: 5ms QueryPerformanceCounter:<1微秒 (win2000支持) 精度达到1ms的定时器:多媒体定时器(win95支持) 原理分析:...win32多媒体定时器
因为编程需要以1ms为周期调用一个函数,故在Windows平台上测试了一些定时器,并进行比较,最终选用timeSetEvent作为最终选项。
几个拉跨的定时器精度
select选择模型:15ms
Sleep(1) :15ms
Sleep(1) : 1-2ms //前提:在设置timeBeginPeriod(1)的情况下; // 设置精度为1毫秒
timeGetTime: 5ms
QueryPerformanceCounter:<1微秒 (win2000支持)
C++11 sleep_for(): 15ms
timeSetEvent(1): 0.95-1.05ms之间精度达到1ms的定时器:多媒体定时器(win95支持)
原理分析:多媒体定时器被创建后,应用程序有一个定时器消息队列,系统以1ms(最高精度)的周期向程序发送定时器消息。当应用程序收到消息时,调用回调函数。此回调函数优先级非常高(最高),甚至可以将Sleep的精度压缩到1ms(通过屏蔽Sleep的方法)(普通线程为15ms,即便是将优先级拉到最高)。当回调函数的执行时间大于1ms (内部有如Sleep(1000))或者长耗时循环操作,会导致定时器消息积压,当挤压消失,系统会在1ms内多次(最高速度)调用回调函数 t<1ms,直到定时器消息队列为空,然后恢复1ms周期。#pragma comment(lib,"winmm.lib") class X{ static void CALLBACK timeOnArrive(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2); } timeSetEvent(1, 0, (LPTIMECALLBACK)timeOnArrive, (DWORD_PTR)this, TIME_PERIODIC);
-
高精度ms级定时器:多媒体定时器
2022-01-25 09:50:58高精度的ms级定时器,多媒体定时器1.背景
在项目上使用MFC的OnTimer(UINT_PTR nIDEvent)定时器时,发现他的响应级别低,精度不高,满足不了ms级别的定时,其后发现有一个多媒体定时器,它使用线程来进行定时,响应级别高,速度快,基本能满足3-4ms的定时需求。
2.多媒体定时器使用流程
3.多媒体定时器的使用
3.1 包含头文件
#include <MMSystem.h> #pragma comment(lib,"Winmm.lib")
3.2 创建定时线程和定时时间
timeBeginPeriod(3); int timeID2 = timeSetEvent(time, 1, (LPTIMECALLBACK)Timecallback, 1, TIME_ONESHOT);
MMRESULT timeSetEvent( UINT uDelay, UINT uResolution, LPTIMECALLBACK lpTimeProc, WORD dwUser, UINT fuEvent )
参数说明:
- uDelay:以毫秒指定时的周期
- Uresolution:以毫秒指定延时的精度,数值越小定时器事件分辨率越高。缺省值为1ms。
- LpTimeProc:指向一个回调函数,该回调函数包含需要定时执行的代码。
- DwUser:存放用户提供的回调数据。
- FuEvent:指定定时器事件类型:
- TIME_ONESHOT:uDelay毫秒后只产生一次事件。
- TIME_PERIODIC :每隔uDelay毫秒周期性地产生事件。
3.3 销毁定时器
定时结束后,会调用指定的回调函数,在该函数中执行需要的操作
static void CALLBACK Timecallback(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2) { CshiguanjiemianDlg* fatherDlg = (CshiguanjiemianDlg*)::theApp.GetMainWnd(); if (dwUser == 1) { timeKillEvent(fatherDlg->timeID2); timeEndPeriod(3); } return; }
函数原型
void CALLBACK TimeProc( UINT uID, UINT uMsg,DWORD dwUser,DWORD dw1,DWORD dw2);
- uID:时间事件标识符,当定时器被建立时,timerSetEcent函数返回该标识符。
- uMsg:保留,未使用。
- dwUser:由timeSetEvent函数的dwUser参数提供的用户实例数据。
- dw1 and dw2 :保留字,未使用。
调用该回调函数后,在TIME_ONESHOT的情况下首先要对调用timeKillEvent(fatherDlg->timeID2)函数销毁指定ID的定时事件,然后调用timeEndPeriod(3),销毁指定的线程;
简单例程:https://download.csdn.net/download/qq_44733143/77859098?spm=1001.2014.3001.5503
-
multi-timer, 多定时器是Pebble的最佳定时器和秒表应用.zip
2019-10-10 09:43:25multi-timer, 多定时器是Pebble的最佳定时器和秒表应用 多定时器是Pebble的最佳定时器和秒表应用。你可以根据需要创建任意数量的独立计时器和秒表。随着 3.0的发布,计时器将在完成时启动应用程序,这意味着你可以以... -
linux下的多定时器实现
2010-08-25 01:05:57文件列表:timer.h,timer.c 功能:实现了linux下的多定时器,采用双向链表来维护定时器列表,用户可利用其中的接口来创建定时器,并注册超时回调函数。时钟计时采用select系统调用来实现。 -
VS2010MFC多媒体定时器
2014-03-31 21:24:07找多媒体找了长时间的,试了好几个网上说的方案,都没有成功。最后有下载了一个这个源代码,还是运行不了,经分析可能是vs2010的开发环境不适应吧,将消息处理函数修改后能够成功运行。 希望对你有帮助! -
test(多媒体定时器的定制和使用方法).rar
2021-09-14 22:45:16test(多媒体定时器的定制和使用方法).rar -
多媒体定时器的简单使用示例
2013-07-19 17:34:54多媒体定时器的简单使用示例,更精确的定时器使用mmtimer -
VC多媒体定时器实例
2010-04-17 17:18:39利用VC多媒体定时器编写的定时器小程序,可供用VC进行精确定时或者定时控制,实时控制的编程参考。内附详细的过程说明 -
最简单易学的多媒体定时器应用
2013-12-22 17:37:28非常简单、易学的多媒体定时器应用,适合初学者,一看就明白 -
「C++ & MFC」 “多媒体定时器实例”讲解
2019-03-17 21:59:01本博客在MFC工程中,完成了对创建多媒体定时器和读文档功能的应用。 首先要包含MMSystem.h头文件,还要添加以下代码 #pragma comment(lib,"winmm.lib") 创建多媒体定时器由四个函数合作完成: 执行创建:Create...一、前言
本博客在MFC工程中,完成了对创建多媒体定时器和读文档功能的应用。
二、技术实现
首先要包含MMSystem.h头文件,还要添加以下代码 #pragma comment(lib,"winmm.lib")
创建多媒体定时器由四个函数合作完成:
- 执行创建:CreateTimer();
- 执行回调:TimeProc();
- 执行内容:OnTimer();
- 执行销毁:DestroyTimer();
1. 创建函数 CreateTimer()
使用这个函数创建一个多媒体定时器
UINT CMy11Dlg::CreateTimer() { //create the timeryte+89+121741 01234 // Create a periodic timer timeBeginPeriod(1); timerID = timeSetEvent(1,1,TimeProc,(DWORD)this,TIME_PERIODIC); return timerID; }
(1)timeBeginPeriod(1); //开始一个新段,当使用多个‘多媒体定时器’时,()内的数字不能重复;
(2)启动多媒体定时器函数。
MMRESULT timeSetEvent( UINT uDelay, UINT uResolution, LPTIMECALLBACK lpTimeProc, WORD dwUser, UINT fuEvent )
参数说明:
- uDelay:以毫秒指定时的周期
- Uresolution:以毫秒指定延时的精度,数值越小定时器事件分辨率越高。缺省值为1ms。
- LpTimeProc:指向一个回调函数,该回调函数包含需要定时执行的代码。
- DwUser:存放用户提供的回调数据。
- FuEvent:指定定时器事件类型:
- TIME_ONESHOT:uDelay毫秒后只产生一次事件。
- TIME_PERIODIC :每隔uDelay毫秒周期性地产生事件。
2. 回调函数:TimeProc()
每一次多媒体定时器循环都会从这个函数开始,所以我们叫它回调函数。
void CALLBACK CMy11Dlg::TimeProc(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2) { CMy11Dlg* pdcpackerdlg = (CMy11Dlg*)dwUser; m_num++; pdcpackerdlg->m_number=m_num; pdcpackerdlg->OnTimer(1); //之所以有数字1,是因为你可以把它内部设置成switch选择框架 }
(1)函数原型:
void CALLBACK TimeProc( UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2 );
对于应用程序定义的函数名TimeProc为一个占位符。
(2)参数:
- uID:时间事件标识符,当定时器被建立时,timerSetEcent函数返回该标识符。
- uMsg:保留,未使用。
- dwUser:由timeSetEvent函数的dwUser参数提供的用户实例数据。
- dw1 and dw2 :保留字,未使用。
*应用程序不能从回调函数内部调用系统定义的函数,除了PostMessage, timeGetSystemTime, timeGetTime, timeSetEvent.TimeKillEvent, midiOutShortMsg, midiOutLongMsg和OutpuitDebugString。
3. 执行函数:OnTimer()
把你希望多媒体定时器循环执行的内容写在这个函数内。这里执行函数的名字你可以自定义,并不一定要以OnTimer()为名。
void CMy11Dlg::OnTimer(UINT nIDEvent) { // TODO: Add your message handler code here and/or call default switch (nIDEvent) { case 1: { Sim_Data_Write<<TestData[0]<<" "<<TestData[1]<<" "<<TestData[2]<<" " <<TestData[3]<<" "<< TestData[4]<<" "<<TestData[5]<<" "<<TestData[6]<<" " <<TestData[7]<<" "<<TestData[8]<<" "<<endl; CString str; str.Format("%d",m_number); GetDlgItem(IDC_EDIT1)->SetWindowText(str); CString str1; str1.Format("%f",TestData[0]); GetDlgItem(IDC_test0)->SetWindowText(str1); CString str2; str2.Format("%f",TestData[1]); GetDlgItem(IDC_test1)->SetWindowText(str2); CString str3; str3.Format("%f",TestData[8]); GetDlgItem(IDC_test8)->SetWindowText(str3); break; } } CDialog::OnTimer(nIDEvent); }
这里我们执行的内容是,读取一个.txt文件,并将文件中的内容显示到MFC界面内。
4. 销毁函数:DestroyTimer()
执行此函数后将停止多媒体定时器循环,并销毁此定时器。
void CMy11Dlg::DestroyTimer() { timeKillEvent(timerID); timeEndPeriod(1); }
例程执行结果:
至此,一个完整的多媒体定时器例程就创建完毕了,注意不要忘记添加多媒体定时器的头文件。
小白将一个完整的例程放在这里,上面的代码也均来自此例程
功能包括:多媒体定时器、.txt文档读操作。
-
linux 多线程安全定时器
2017-08-16 22:55:57timerfd的定时器和epoll监听 比较通用 里面有makefile 直接编译即可