QT5線程關閉
QThread析構函數的說明:
請注意,刪除一個QThread對象不會停止它管理的線程的執行。 刪除正在運行的QThread(即isFinished()返回false)將導致程序崩潰。 在刪除QThread之前等待finished()信號。
從Qt4.8起,可以釋放運行剛剛結束的線程對象,通過連接finished()信號到QObject::deleteLater()。
QThread類
quit()
告訴線程的事件循環以return 0(成功)退出。 相當於調用QThread :: exit(0)。如果線程沒有事件循環,這個函數什么也不做。
wait()
阻塞線程,直到滿足以下任一條件:
與此QThread對象關聯的線程已經完成執行(即從run()返回)。 如果線程完成,該函數將返回true。 如果線程尚未啟動,它也返回true。
時間毫秒已經過去了。 如果時間是ULONG_MAX(默認值),那么等待永遠不會超時(線程必須從run()返回)。 如果等待超時,此函數將返回false。
QMutex類
在QMutex的使用中,我們關注以下4個方法和2個屬性:
1、QMutex ()//構造1個mutex 默認構造參數為非遞歸
2、lock ()//鎖
3、tryLock ()//嘗試着鎖
4、unlock ()//釋放鎖
另外兩個屬性是:遞歸和非遞歸。如果這個mutex是遞歸的話,表明它可以被一個線程鎖多次,也就是鎖和解鎖中再嵌套鎖和解鎖;非遞歸的話,就表明mutex只能被鎖一次。
QMutexLocker類
相當於QMutex的簡化,提供了簡化了的互斥上的操作(也即簡化了的加鎖和解鎖)。
使用詳情可看幫助文檔;
關閉線程
一.QMutex互斥鎖 + bool成員變量。quit(),wait();
//線程處理函數
public: void dis() { QMutex mutex; while(1) { mutex.lock(); if(mtread.stop) break; mutex.unlock(); //實際運行代碼 //.....
} } //關閉線程函數
mtread.stop = true; QThread->quit(); QThread->wait();
以上還是存在mutex.unlock();沒被調用的情況,可用QMutexLocker類優化
二.Qt5.2以后添加的新方法:requestInterruption() + isInterruptionRequested()
isInterruptionRequested()
如果一個應該停止的任務在此線程上運行,則返回true。 requestInterruption()可以請求中斷。
這個功能可以用來使長時間運行的任務干凈地中斷。 建議在耗時長的運行函數中定期執行此操作。 注意不要太頻繁地調用,以保持較低的開銷。
//線程處理函數
public: void dis() { while(QThread::currentThread()->isInterruptionRequested()) { //實際運行代碼 //.....
} } //關閉線程函數
QThread->requestInterruption(); QThread->quit(); QThread->wait();
isInterruptionRequested() 往往配合QThread::currentThread()返回一個指向使用本函數線程的指針
關於connect第五個參數,連接類型: 1)自動連接(AutoConnection),默認的連接方式,如果信號與槽,也就是發送者與接受者在同一線程,等同於直接連接;如果發送者與接受者處在不同線程,等同於隊列連接。 2)直接連接(DirectConnection),當信號發射時,槽函數立即直接調用。無論槽函數所屬對象在哪個線程,槽函數總在發送者所在線程執行。
3)隊列連接(QueuedConnection),當控制權回到接受者所在線程的事件循環時,槽函數被調用。槽函數在接受者所在線程執行。
- 阻塞隊列(BlockingQueuedConnection)
- 非阻塞隊列(UniqueConnection
GUI界面假死的處理
在GUI程序中,主線程也叫GUI線程,因為它是唯一被允許執行GUI相關操作的線程。對於一些耗時的操作,如果放在主線程中,就是出現界面無法響應的問題。這種問題的解決一種方式是,把這些耗時操作放到次線程中,還有一種比較簡單的方法:在處理耗時操作中頻繁調用QApplication::processEvents()。這個函數告訴Qt去處理那些還沒有被處理的各類事件,然后再把控制權返還給調用者。
QElapsedTimer et; et.start(); while(et.elapsed()<300) QCoreApplication::processEvents();