定時(shí)器的作用在Qt開(kāi)發(fā)中老虫,應(yīng)用場(chǎng)景比較豐富譬巫,比如輪詢(xún)定時(shí)任務(wù)、模擬進(jìn)度條、延時(shí)動(dòng)畫(huà)展示伞剑、計(jì)算時(shí)間間隔等等。但在實(shí)際的開(kāi)發(fā)中濒生,定時(shí)器常常是非必要不使用的原則见秤。了解定時(shí)器的實(shí)現(xiàn)原理,可以更好的判斷在不同應(yīng)用場(chǎng)景下定時(shí)器的使用
1.定時(shí)器時(shí)間精度依賴(lài)于系統(tǒng)的硬件
定時(shí)器的精度依賴(lài)于系統(tǒng)硬件1ms的定時(shí)精度遂蛀,同時(shí)在系統(tǒng)忙碌的情況下無(wú)法確保準(zhǔn)時(shí)觸發(fā)timeout谭跨。因此在某些場(chǎng)景下,依賴(lài)前置條件需要延時(shí)初始化或延時(shí)調(diào)用函數(shù)李滴,通過(guò)定時(shí)器延時(shí)觸發(fā)初始化螃宙,延時(shí)時(shí)間的設(shè)置與timeout的觸發(fā)依賴(lài)于硬件性能(部分系統(tǒng)還會(huì)限制定時(shí)器的數(shù)量),不同機(jī)器表現(xiàn)會(huì)有所不同所坯,不能確切保證程序的先后執(zhí)行情況谆扎。
2.定時(shí)器的實(shí)現(xiàn)原理
Qt定時(shí)器的使用依賴(lài)于當(dāng)前線程的事件循環(huán)調(diào)度,在事件循環(huán)中芹助,監(jiān)聽(tīng)系統(tǒng)消息隊(duì)列中的WM_TIMER事件燕酷,并翻譯成QEvent::Timer發(fā)送給接收對(duì)象,實(shí)現(xiàn)定時(shí)器的超時(shí)周瞎。
int timerId = d->threadData->eventDispatcher.load()->registerTimer(interval, timerType, this);
向系統(tǒng)注冊(cè)定時(shí)器事件QEventDispatcherWin32::registerTimer
在 Windows 操作系統(tǒng)中苗缩,注冊(cè)定時(shí)器的底層原理涉及到操作系統(tǒng)內(nèi)核、計(jì)時(shí)器機(jī)制声诸、以及消息傳遞系統(tǒng)酱讶。下面是一個(gè)簡(jiǎn)要的概述,說(shuō)明在 Windows 中注冊(cè)定時(shí)器的底層原理:
1.定時(shí)器對(duì)象創(chuàng)建
2.插入定時(shí)器隊(duì)列:
系統(tǒng)會(huì)將新創(chuàng)建的定時(shí)器對(duì)象插入到一個(gè)全局定時(shí)器隊(duì)列中彼乌。這個(gè)隊(duì)列通常是一個(gè)基于時(shí)間的優(yōu)先級(jí)隊(duì)列泻肯,以便高效地管理多個(gè)定時(shí)器渊迁。
3.系統(tǒng)時(shí)鐘管理:
操作系統(tǒng)維護(hù)一個(gè)全局的系統(tǒng)時(shí)鐘,用于跟蹤系統(tǒng)的當(dāng)前時(shí)間灶挟。當(dāng)一個(gè)新的定時(shí)器被添加到定時(shí)器隊(duì)列中時(shí)琉朽,系統(tǒng)會(huì)根據(jù)定時(shí)器的超時(shí)間隔計(jì)算出定時(shí)器的到期時(shí)間,并將其與當(dāng)前系統(tǒng)時(shí)間進(jìn)行比較稚铣。
4.系統(tǒng)時(shí)鐘滴答:
操作系統(tǒng)內(nèi)核有一個(gè)硬件時(shí)鐘(通常是系統(tǒng)的計(jì)時(shí)器中斷)箱叁,定期(通常是每隔幾毫秒)觸發(fā)一個(gè)中斷。這些中斷用于更新系統(tǒng)時(shí)鐘惕医,并檢查定時(shí)器隊(duì)列中是否有任何定時(shí)器已經(jīng)到期耕漱。
5.檢查定時(shí)器隊(duì)列:
每次系統(tǒng)時(shí)鐘中斷觸發(fā)時(shí),操作系統(tǒng)會(huì)檢查定時(shí)器隊(duì)列抬伺,查看是否有任何定時(shí)器已經(jīng)到期螟够。如果發(fā)現(xiàn)一個(gè)或多個(gè)定時(shí)器到期,系統(tǒng)會(huì)將這些定時(shí)器的到期事件插入到相應(yīng)線程或窗口的消息隊(duì)列中峡钓。
6.消息處理:
當(dāng)一個(gè)定時(shí)器事件被插入到消息隊(duì)列中時(shí)妓笙,目標(biāo)窗口或線程的消息循環(huán)會(huì)處理這個(gè)事件。通常能岩,這涉及到向窗口過(guò)程(Window Procedure)發(fā)送一個(gè) WM_TIMER 消息给郊。
7.定時(shí)器的銷(xiāo)毀
當(dāng)調(diào)用 KillTimer 函數(shù)時(shí),操作系統(tǒng)會(huì)從定時(shí)器隊(duì)列中移除指定的定時(shí)器對(duì)象捧灰,并取消其與窗口或線程的關(guān)聯(lián)淆九。
定時(shí)器的使用是向系統(tǒng)注冊(cè)定時(shí)器,系統(tǒng)判斷超時(shí)會(huì)通知定時(shí)器關(guān)聯(lián)的窗口函數(shù)進(jìn)行響應(yīng)毛俏,因此炭庙,在桌面應(yīng)用程序開(kāi)發(fā)過(guò)程中,如果非必要地使用了定時(shí)器煌寇,軟件處于在用戶計(jì)算機(jī)待機(jī)的情況下焕蹄,會(huì)定時(shí)觸發(fā)timeout,調(diào)用應(yīng)用程序阀溶,造成待機(jī)耗電影響腻脏。
在多線程應(yīng)用程序中,您可以在任何具有事件循環(huán)的線程中使用QTimer银锻。要從非gui線程啟動(dòng)事件循環(huán)永品,請(qǐng)使用QThread::exec()。Qt使用定時(shí)器的線程關(guān)聯(lián)來(lái)確定哪個(gè)線程將發(fā)出timeout()信號(hào)击纬。因此鼎姐,必須在其線程中啟動(dòng)和停止計(jì)時(shí)器;不可能從另一個(gè)線程啟動(dòng)計(jì)時(shí)器。