定时器和多线程的不同

      最近在做项目的时候,遇到了视频采集图像时。使用定时器与或使用多线程有些纠结。原先用了定时器测试了,因为项目需要占用较多的cpu,所以很明显图像显示比较卡。

所以网上查了下。贴出来大家学习学习。

     

     软件定时器和多线程在控制工程中有着非常广泛的使用,主要是因为在控制过程中,会出现大量的Socket通信和串口通信数据量,仔细想了想,觉得这两样东西还是有比较的价值的,很多初学者(我也是。。。)可能会在这两样东西上困惑,现简单比较一下。

       首先注意: 线程消息队列中WM_PAINT,WM_TIMER只有在Queue中没有其他消息的时候才会被处理,WM_PAINT消息还会被合并以提高效率。其他所有消息以先进先出(FIFO)的方式被处理。http://zhidao.baidu.com/question/176892832.html?fr=ala0。

1 软件定时器

很多同学在工程中喜欢使用软件定时器,因为其使用简单,仅需设置一个时长和其OnTime事件即可使用。确实,软件定时器在某些持续性不强的重复性工作中效率还是不错的,但是也有着很大的缺点。

缺点1,速度:软件定时器的精度比较低,这是由Windows不实时的特性所决定的,在XP下,如果关闭所有能关闭的进程,MFC的软件定时器可以达到接近15ms的精度,而在Win2000下,其能达到接近10ms的精度。但是实际情况是,有些进程是不可以关闭的,比如说数据库服务器,所以MFC的软件定时器能够达到的精度一般情况下在40ms左右,BCB和delphi就更差一点,大概在55ms左右。QueryPerformanceCounter倒是可以大幅提高精度,但是稳定性欠佳。

缺点2,效率:软件定时器其本质实际上是在消息循环中处理WM_TIMER消息,而WM_TIMER消息在消息队列中是一个低级别的消息,所以定时器并不能完全保证处理时间间隔的准确性。另外,Timer占用的是主线程的资源,看似并行实际上是串行,所以窗体的消息队列一旦堵塞,就会造成系统假死或者运行缓慢,这对于UI来说几乎是无法忍受的。

2 多线程

多线程技术是在控制工程中常用的技术,因为在闭环系统中有着大量的数据处理,这些处理显然不可能放在主线程中处理,绝大多数都是在线程中使用。多线程的优点比较明显,就是把费劲的东西扔到后台去,而且对CPU的利用率比较高。如果控制的好,多线程几乎是没有什么缺点的,但实际上控制的好的并不多……原因如下:

1、时间片不可控,抢CPU资源的事情~一般人说不清;

2、同步比较复杂,容易发生死锁,3条线程同步一般就能把人折腾死。同步我比较喜欢用临界区,原因也很简单:因为临界区比较简单……

http://cache.baidu.com/c?m=9f65cb4a8c8507ed4fece7631046893b4c4380146d96864968d4e414c422461e4d6ce4be2329171980852d3d5aeb1e41eaf235702a0125aa99cd954dd8b8992e2a883034074fc70358c75cf28b102ad650944d9aa50e96c9e74290b9d3a3c82557dd27006d81809c2a7303bb19e71541f4d7ed5f632b07caec27148e4e7659885347a136fff7331e10f0f3ca2846d45ad3766595&p=8b2a9204809b1fb906bd9b7f0d57&user=baidu

///

1.软件开发当中经常需要用到这两个好东东,但是两个使用起来是有很大区别的哦,
  如果在PC上可能效果差不多,如果放到CE小手持设备可能就很明显的感觉得到;
  如果是定时器,如果是在有界面处理的APP中,你会感觉到程序在一顿一顿的;
  当然,如果处理的东西本来就很少很少,用两者是没有感觉的,但是用在很大的
  耗时处理上面,效果就出来了;
  为什么呢?因为Timer来了优先级很高所以会先去处理定时器例程,如果处理很
  耗时,那一定会一顿一顿的;
  Thread就不同了,CE也是抢占式OS,多线程时是时间轮片处理的;所以如果用线程
  的话也可以达到定时器的效果,并且不会感觉到一顿一顿的BUG;因为无论你的处理
  有多耗时,时间片一到就又去处理别的了;如果处理的内容很独立,没有与其他
  线程有耦合的话,是可以这样做的;

2.

 

 SetTimer函数和WM_TIMER消息是Win32 api中最基本的玩意儿了,任何初学Win32 api编程的人都应该对此很熟悉吧。在这篇文章中,让我们来深入了解一下和SetTimer相关的使用和应用。

  UINT_PTR SetTimer(

  HWND hWnd,

  UINT_PTR nIDEvent,

  UINT uElapse,

  TIMERPROC lpTimerFunc

  );

  我们经常使用的情况是hWnd不为NULL,lpTimerFunc为NULL,在这种情况下系统每隔nIDEvent毫秒会向hWnd窗口投递WM_TIMER消息。唯一需要注意的是:

  1.自2000起,uElapse范围是USER_TIMER_MINIMUM到USER_TIMER_MAXIMUM。超出得话,uElapse设置为1。

  2.WM_TIMER消息其实是在DispatchMessage函数中直接调用hWnd的窗口过程,并且优先级很低,只有在消息队列中没有其它消息的情况下,DispatchMessage才会考虑WM_TIMER。

  3.使用相同的nIDEvent可以重置这个Timer,并且KillTimer(hWnd,nIDEvent)来销毁这个Timer。

  我们再来考虑hWnd为NULL的情况:

  1.首先,最重要的是KillTimer时,传入的Timer Id必须是SetTimer的返回值,而不是调用SetTimer时传入的nIDEvent参数。

  2.调用SetTimer时,如果nIDEvent为0或者是其它没有被使用的Timer Id,则SetTimer会返回一个新的Timer Id。否则,就是重新设置这个Timer。

  3.如果有lpTimerFunc的话,则lpTimerFunc的参数nIDEvent是SetTimer返回的值,而不是你调用SetTimer时传入的值。

  最后看一下lpTimerFunc不为NULL的情况:lpTimerFunc会在DispatchMessage函数中被直接调用,而不会去调用hWnd的窗口过程(也就是说收不到这个消息),无论hWnd是不是NULL。(这里,msdn中貌似有点问题,SetTimer的Remark部分说lpTimerFunc会在默认窗口中被调用,而WM_TIMER中说lpTimerFunc在DispatchMessage中被调用)

  应用

  使用lpTimerFunc可以做一个延时的操作,或者把某些操作推迟到下一个消息循环,而不需要为窗口定义一个新的Timer Id。

  例如,我很喜欢这样写:

  struct _DATA

  {

  //....

  };

  void CALLBACK TimerProc(HWND hwnd,

  UINT uMsg,

  UINT_PTR idEvent,

  DWORD dwTime)

  {

  _DATA * data = (_DATA*)idEvent;

  KillTimer(hwnd,idEvent);

  //do something

  free(data);

  }

  _DATA * data = (_DATA*)malloc(sizeof(_DATA));

  SetTimer(AfxGetMainWindow()->m_hWnd,(UINT_PTR)data,10,&TimerProc);

  首先,使用了TimerProc,不会使窗口收到WM_TIMER消息,那样可以使用idEvent来传递自定义数据而不会和窗口自己使用的Timer id冲突。

  其次,第一个参数hWnd不能为NULL,否则TimerProc的idEvent参数就不是你传入的自定义数据了。

  最后,msdn说SetTimer不能跨线程使用,所以最好不要用这样的方法在向ui线程来插入代码,还是老老实实的发消息吧。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/352563.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

华为s8600手机驱动_只有手机才能快充?华为MateBook X的灵巧快充解放你的续航焦虑-华为 ——快科技(驱动之家旗下媒体)-...

充电,永远是数码科技圈必不可少的话题。然而,想要好好给设备充电太并不容易。每次外出,为了防止手机没电,大家的兜里必然要揣着一个大容量的充电宝才安心,这也是手机快充最初诞生的原因。快充技术指的是通过技术手段&a…

linux系统编程之进程(七):system()函数使用

一,system()理解 功能:system()函数调用“/bin/sh -c command”执行特定的命令,阻塞当前进程直到command命令执行完毕 原型: int system(const char *command); 返回值: 如果无法启动shell运行命令,system将…

Scrapy安装介绍

Scrapy安装介绍 一、 Scrapy简介 Scrapy is a fast high-level screen scraping and web crawling framework, used to crawl websites and extract structured data from their pages. It can be used for a wide range of purposes, from data mining to monitoring and aut…

数据库常用语句整理

数据库常用语句整理 --查询 select * from emp;--oracle 分页 SELECT * FROM (SELECT rownum AS rnum, e.*FROM emp eWHERE rownum < 10 ) WHERE rnum > 5;--复制表 CREATE TABLE new_table AS SELECT * FROM old_table; 参考资料 https://www.techonthenet.com/sql/tabl…

c语言n次方怎么输入_C语言实现斐波拉契数列

C语言实现斐波拉契数列教程怎么使用 C 语言实现计算斐波拉契数列的第 N 项的值&#xff1f;C语言实现斐波拉契数列详解背景知识斐波那契数列是一组第一位和第二位为 1&#xff0c;从第三位开始&#xff0c;后一位是前两位和的一组递增数列&#xff0c;像这样的&#xff1a;1、1…

junit 测试mvc_Spring MVC控制器JUnit测试

junit 测试mvcJUnit测试Spring MVC控制器并非易事 。 但是最近&#xff0c;一个新项目 &#xff08;即将在Spring推出&#xff09;提供了新的工具来简化此工作。 这篇文章说明了如何通过JUnit测试来测试一个简单的控制器。 该代码是JUnit Testing Spring Service和DAO&#xff…

python中if __name__ == '__main__': 的解析

当你打开一个.py文件时,经常会在代码的最下面看到if __name__ __main__:,现在就来介 绍一下它的作用. 模块是对象&#xff0c;并且所有的模块都有一个内置属性 __name__。一个模块的 __name__ 的值取决于您如何应用模块。如果 import 一个模块&#xff0c;那么模块__name__ 的…

LuoguP1268树的重量【构造/思维】By cellur925

题目传送门 Description 给你一个矩阵$M$&#xff0c;$M(i,j)$表示$i$到$j$的最短距离。定义树的重量为树上各边权之和&#xff0c;对于任意给出的合法矩阵$M$&#xff0c;已知它所能表示树的重量是唯一确定的。给出一个矩阵&#xff0c;求它所表示的树的重量。 Sol 这道题我想…

pydev插件安装方法

eclipse 版本&#xff1a; PYDEV:附件在本博客资源下载 下载附件后解压缩,将features和plugins个目录复制粘贴到eclipse相对应的目录下面&#xff0c;然后在启动Eclipse&#xff0c;在Help&#xff0d;》check for UPdates&#xff0c;然后弹出的界面即可看到pydev的插件。 …

将速度加快到自己的个人代码生成器中

Speedment是一个开放源代码工具箱 &#xff0c;可用于生成Java实体和管理器以与数据库进行通信。 如果您需要域模型的对象关系映射&#xff0c;那么这很好&#xff0c;但是在某些情况下&#xff0c;您可能希望使用数据库作为模板来生成完全不同的东西。 在本文中&#xff0c;我…

python3常用模块_Python3 常用模块1

os模块 通过os模块我们可以与操作系统交互, 控制文件和文件夹 对文件夹操作 # 判断是否为文件夹 os.path.isdir() # 创建文件夹 os.mkdir() # 删除文件夹 os.rmdir() # 列出文件夹内所有文件(返回列表) os.listdir() # 当前文件所在文件夹路径 os.getcwd() # 所在文件夹的路径 …

matlab求最短路径代码_【高等数学】复数,通往真理的最短路径

看图学数学&#xff01;可能是中国最好的高等数学的基础概念讲解&#xff0c;深入浅出、形象生动。没有高深的数学符号&#xff0c;只有你能懂的数学内容。在实数域中&#xff0c;连接两个真理的最短的路径是通过复数域----雅克阿达马现代数学家对复数的看法如斯&#xff0c;无…

怎么解决python Non-ASCII character错误

第一次接触Python&#xff0c;今天刚在Eclipse上安装完PyDev插件准备开始编程&#xff0c;用用简单例子进行调试竟然出现这样的错误&#xff0c; SyntaxError: Non-ASCII character \xef in file C:\Users\Administrator.NUY67O2SLHT6KM0\workspace\Hello World\scr\Hello.py …

Win7下VS2008破解方法

在Win7系统下&#xff0c;无法像xp下通过“控制面板”卸载的方法重新输入序列号来破解VS2008。 但可以通过以下几个步骤来破解&#xff1a; 1.首先需要安装VS2008&#xff0c;可以安装VS2008专业版90天试用版或VS2008团队版90天试用版都行。 VS2008专业版90天试用版下载地址&am…

五、Kafka 用户日志上报实时统计之应用概述

一、kafka 回顾 1.简介 Kafka 的业务 业务场景&#xff1a; 解除耦合  增加冗余  提高可扩展性  Buffering  异步通信2.介绍 Kafka 的应用场景 Push MessageWebsite Tracking日志收集中心3.实时统计平台搭建注意事项 实时统计平台搭建注意事项&#xff1a; HA特性核心文…

html5移动web开发黑马掌上商城_这套web前端与移动开发教程,帮助了众多小白转行就业...

前端即网站前台部分&#xff0c;运行在PC端&#xff0c;移动端等浏览器上展现给用户浏览的网页。随着互联网技术的发展&#xff0c;HTML5&#xff0c;CSS3&#xff0c;前端框架的应用&#xff0c;跨平台响应式网页设计能够适应各种屏幕分辨率&#xff0c;完美的动效设计&#x…

c++ 使用socket实现C/S端文件的下载传输

首先是服务器端&#xff0c;大致说下流程&#xff1a;服务器创建线程去处理应答accept()&#xff0c;当接受到客户端连接请求时&#xff0c;首先获取要发送的指定的文件数据总大小给客户端&#xff0c;接着就是循环读取要发送的文件数据流向客户端发送文件数据&#xff0c;每次…

Python报错UnicodeDecodeError: ‘ascii’ codec can’t decode byte 0xe0 in position 0: ordinal not in range

Windows 7机器上安装Python2.7后&#xff0c;下载一些Package包进行setup时总是报错UnicodeDecodeError&#xff0c;如下&#xff1a; File "C:\Python27\lib\mimetypes.py", line 250, in enum_types ctype ctype.encode(default_encoding) # omit in 3.x! Unicode…

[MEGA DEAL]专家级Java捆绑包新手(96%)

在世界上最受欢迎的编程语言中从零变成英雄 嘿&#xff0c;怪胎&#xff0c; 本周&#xff0c;在我们的JCG Deals商店中 &#xff0c;我们提供了一个极端的报价 。 我们提供的专家Java捆绑版新手 仅售39美元&#xff0c;而不是原始价格1180美元 &#xff0c;是的&#xff0c…

对二分法思想的体会 及 结队编程情况汇报

算法课第二章作业 1. 对二分法思想的体会&#xff1a; 二分法是分治法的一种&#xff0c;当遇到大问题难以解决的时候&#xff0c;可以使用二分法将问题细化&#xff0c;提高效率&#xff0c;减小问题规模。例如二分搜索&#xff0c;有效率高的优点&#xff0c;但是这个优点的实…