日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

定时器和多线程的不同

發布時間:2023/12/2 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 定时器和多线程的不同 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

? ? ? 最近在做項目的時候,遇到了視頻采集圖像時。使用定時器與或使用多線程有些糾結。原先用了定時器測試了,因為項目需要占用較多的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線程來插入代碼,還是老老實實的發消息吧。


創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的定时器和多线程的不同的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。