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();
1 //線程處理函數
2 public: 3 void dis() 4 { 5 QMutex mutex; 6 while(1) 7 { 8 mutex.lock(); 9 if(mtread.stop) break; 10 mutex.unlock(); 11 //實際運行代碼 12 //.....
13 } 14 } 15 //關閉線程函數
16 mtread.stop = true; 17 QThread->quit(); 18 QThread->wait();
以上還是存在mutex.unlock();沒被調用的情況,可用QMutexLocker類優化
二.Qt5.2以后添加的新方法:requestInterruption() + isInterruptionRequested()
isInterruptionRequested()
如果一個應該停止的任務在此線程上運行,則返回true。 requestInterruption()可以請求中斷。
這個功能可以用來使長時間運行的任務干凈地中斷。 建議在耗時長的運行函數中定期執行此操作。 注意不要太頻繁地調用,以保持較低的開銷。
1 //線程處理函數
2 public: 3 void dis() 4 { 5 while(QThread::currentThread()->isInterruptionRequested()) 6 { 7
8 //實際運行代碼 9 //.....
10 } 11 } 12
13 //關閉線程函數
14 QThread->requestInterruption(); 15 QThread->quit(); 16 QThread->wait();
isInterruptionRequested() 往往配合QThread::currentThread()返回一個指向使用本函數線程的指針
關於connect第五個參數,連接類型: 1)自動連接(AutoConnection),默認的連接方式,如果信號與槽,也就是發送者與接受者在同一線程,等同於直接連接;如果發送者與接受者處在不同線程,等同於隊列連接。 2)直接連接(DirectConnection),當信號發射時,槽函數立即直接調用。無論槽函數所屬對象在哪個線程,槽函數總在發送者所在線程執行。
3)隊列連接(QueuedConnection),當控制權回到接受者所在線程的事件循環時,槽函數被調用。槽函數在接受者所在線程執行。
- 阻塞隊列(BlockingQueuedConnection)
- 非阻塞隊列(UniqueConnection
GUI界面假死的處理
在GUI程序中,主線程也叫GUI線程,因為它是唯一被允許執行GUI相關操作的線程。對於一些耗時的操作,如果放在主線程中,就是出現界面無法響應的問題。這種問題的解決一種方式是,把這些耗時操作放到次線程中,還有一種比較簡單的方法:在處理耗時操作中頻繁調用QApplication::processEvents()。這個函數告訴Qt去處理那些還沒有被處理的各類事件,然后再把控制權返還給調用者。
1 QElapsedTimer et; 2 et.start(); 3 while(et.elapsed()<300) 4 QCoreApplication::processEvents();
