91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

wxWidgets第十四課 wxTimer定時器

發布時間:2020-08-06 12:44:13 來源:網絡 閱讀:4138 作者:fengyuzaitu 欄目:系統運維

說明

    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鏈表,減少每個定時器的剩余時間,并把到期的定時器設置為已就緒


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

武定县| 驻马店市| 子洲县| 新安县| 阳原县| 天台县| 云霄县| 苍梧县| 如东县| 威信县| 龙泉市| 西充县| 牡丹江市| 宁明县| 沁源县| 临沂市| 施秉县| 普兰店市| 孟津县| 阳新县| 扶绥县| 平顶山市| 阳谷县| 柘城县| 修水县| 宁津县| 辽宁省| 容城县| 如东县| 城步| 临澧县| 确山县| 象山县| 兴和县| 积石山| 岳普湖县| 剑川县| 阜宁县| 岐山县| 潼南县| 双城市|