嵌入式軟件開發(fā)過程中,基本都會(huì)用到“延時(shí)”,本文分享幾種Qt種延時(shí)處理方法。
一、阻塞型延時(shí)
阻塞的原理就是:在延時(shí)期間,本線程的事件循環(huán)得不到執(zhí)行。
1、QThread類的sleep()
最簡(jiǎn)單的延時(shí)方法就是使用QThread類的sleep(n)、msleep(n)、usleep(n),這幾個(gè)函數(shù)的不良后果就是,GUI會(huì)在延時(shí)的時(shí)間段內(nèi)失去響應(yīng),界面卡死,所以,這三個(gè)函數(shù)一般用在非GUI線程中。
QThread::msleep(50);//阻塞延時(shí)50ms
2、使用定時(shí)器:死等
voidDelay_MSec_Suspend(unsignedintmsec)
{
QTime_Timer=QTime::currentTime().addMSecs(msec);
while(QTime::currentTime()
二、非阻塞延時(shí)
原理無非就是利用事件循環(huán),有兩種原理:
1、處理本線程的事件循環(huán)
在等待中,不斷強(qiáng)制進(jìn)入當(dāng)前線程的事件循環(huán),這樣可以把堵塞的事件都處理掉,從而避免程序卡死
voidDelay_MSec(unsignedintmsec)
{
QTime_Timer=QTime::currentTime().addMSecs(msec);
while(QTime::currentTime()
2、使用子事件循環(huán)
創(chuàng)建子事件循環(huán),在子事件循環(huán)中,父事件循環(huán)仍然是可以執(zhí)行的
voidDelay_MSec(unsignedintmsec)
{
QEventLooploop;//定義一個(gè)新的事件循環(huán)
QTimer::singleShot(msec,&loop,SLOT(quit()));//創(chuàng)建單次定時(shí)器,槽函數(shù)為事件循環(huán)的退出函數(shù)
loop.exec();//事件循環(huán)開始執(zhí)行,程序會(huì)卡在這里,直到定時(shí)時(shí)間到,本循環(huán)被退出
}
三、耗時(shí)代碼的處理
假設(shè)有這樣的應(yīng)用情景:點(diǎn)擊某個(gè)button之后,需要讀入并處理一幅圖像,需要耗時(shí)20秒才能處理完。
在這20s內(nèi),GUI會(huì)失去效應(yīng),界面上的任何元素都無法被點(diǎn)擊,這種情況應(yīng)該怎么辦?方法有兩種:1、用另一個(gè)線程去處理這個(gè)耗時(shí)任務(wù);2、在耗時(shí)任務(wù)中,不斷地去處理本線程的事件循環(huán),以保證GUI的及時(shí)響應(yīng)。
for(i=0;i1000000;?i++)
{
????//QCoreApplication::AllEvents);????//去處理本線程的事件循環(huán),避免本線程被堵塞
????QCoreApplication::AllEvents,?5);//如果不夠頻繁,可以增加第二參數(shù)來緩解卡頓
?
????for(j=0;j1000000;?j++)
????{
????????//QCoreApplication::AllEvents);//處理事件循環(huán),不建議放在這里,可能過于頻繁
????????doSomeThing();
????}
}
一般來說,processEvents()不宜被調(diào)用的過于頻繁,也不宜被調(diào)用的不夠頻繁。過于頻繁的話,一方面會(huì)使線程的響應(yīng)更好,但另一方面會(huì)導(dǎo)致原本就耗時(shí)的任務(wù)變得更加耗時(shí);不夠頻繁的話,顯然可能會(huì)使GUI線程的響應(yīng)變差,例如每500ms才被調(diào)用一次,那么GUI的事件循環(huán)就只能500ms才被處理一次,當(dāng)然,這個(gè)問題可以通過設(shè)定processEvents()的第二個(gè)形參略微得到緩解,更好的做法是,保證被調(diào)的周期<200ms(再小一些更好,看程序需求),這樣不至于肉眼可見的卡頓。
副作用:(特別注意!)
1、在點(diǎn)擊按鈕之后,這個(gè)20s的耗時(shí)任務(wù)開始執(zhí)行,尚未執(zhí)行完畢時(shí),我們點(diǎn)擊了GUI的關(guān)閉按鈕,那么GUI會(huì)立即消失,但是這個(gè)耗時(shí)任務(wù)仍然會(huì)在后臺(tái)執(zhí)行,直到執(zhí)行完畢,進(jìn)程才會(huì)退出。解決辦法:重寫關(guān)閉事件,在關(guān)閉事件的函數(shù)中直接結(jié)束進(jìn)程。
2、在點(diǎn)擊按鈕之后,這個(gè)20s的耗時(shí)任務(wù)開始執(zhí)行,執(zhí)行到第5秒時(shí),我們?cè)俅吸c(diǎn)擊了這個(gè)按鈕,那么QT又會(huì)執(zhí)行一個(gè)新的20s任務(wù),這個(gè)新任務(wù)完成后,又會(huì)接著把第一個(gè)20s任務(wù)從上次被打斷的第5秒繼續(xù)執(zhí)行。如果這個(gè)任務(wù)是可重入的,后果僅僅是被執(zhí)行了兩遍,如果任務(wù)不可重入,那情況就徹底糟糕了。解決辦法:點(diǎn)擊按鈕后把這個(gè)按鈕disable掉,執(zhí)行完再enable
審核編輯 :李倩
-
延時(shí)
+關(guān)注
關(guān)注
0文章
107瀏覽量
25506 -
函數(shù)
+關(guān)注
關(guān)注
3文章
4304瀏覽量
62429 -
嵌入式軟件
+關(guān)注
關(guān)注
4文章
240瀏覽量
26616
原文標(biāo)題:幾種延時(shí)處理方法
文章出處:【微信號(hào):strongerHuang,微信公眾號(hào):strongerHuang】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論