qthread只有run函式是在新執行緒裡的,其他所有函式都在qthread生成的執行緒裡
如果qthread是在ui所在的執行緒裡生成,那麼qthread的其他非run函式都是和ui執行緒一樣的,所以,qthread的繼承類的其他函式盡量別要有太耗時的操作,要確保所有耗時的操作都在run函式裡。
在ui執行緒下呼叫qthread的非run函式(其實也不應該直接呼叫run函式,而應該使用start函式),和執行普通函式無區別,這時,如果這個函式要對qthread的某個變數進行變更,而這個變數在run函式裡也會被用到,這時就需要注意加鎖的問題,因為可能這個變數前幾毫秒剛剛在run中呼叫,再呼叫時已經被另外的執行緒修改了。
安全結束執行緒:
1.工作執行緒
每個程式啟動後擁有的第乙個執行緒稱為主線程,即gui執行緒。qt中所有的元件類和幾個相關的類只能工作在gui執行緒(是唯一允許執行gui相關操作的執行緒),不能工作在次執行緒,次執行緒即工作執行緒,主要負責處理gui執行緒卸下的工作,每個執行緒都有自己的棧
2.多執行緒簡介
qt執行緒類包括:
qthread 提供了跨平台的多執行緒解決方案
qthreadstorage 提供逐執行緒資料儲存
qmutex 提供相互排斥的鎖,或互斥量
qmutexlocker 是乙個輔助類,自動對 qmutex 加鎖與解鎖
qreadwriterlock 提供了乙個可以同時讀操作的鎖
qreadlocker與qwritelocker 自動對qreadwritelock 加鎖與解鎖
qsemaphore 提供了乙個整型訊號量,是互斥量的泛化
qwaitcondition 提供了一種方法,使得執行緒可以在被另外執行緒喚醒之前一直休眠
3.執行緒優先順序
4.執行緒的執行5.執行緒的退出
void quit()
退出執行緒,返回0表示成功,相當於qthread:exit(0)
void exit( int returncode = 0 ) : thread退出event loop,並從exec返回,exec的返回值就是 returncode。通常returncode=0表示成功,其他值表示失敗
void terminate() : 強制結束執行緒,不保證資料完整和資源釋放
setterminationenabled ( bool enabled = true ) : 開啟terminate()
6.執行緒的等待
bool wait ( unsigned long time = ulong_max ) : 執行緒將會被阻塞,等待time毫秒,如果執行緒退出,則wait會返回。wait函式解決多執行緒在執行時序上的依賴
void sleep ( unsigned long secs )
void msleep ( unsigned long msecs )
void usleep ( unsigned long usecs )
7.執行緒的狀態
isrunning() : 執行緒是否執行
isfinished() : 執行緒是否結束
8.執行緒與事件迴圈
qthread中run()的預設實現呼叫了exec(),從而建立乙個qeventloop物件,由qeventloop物件處理執行緒中事件佇列(每乙個執行緒都有乙個屬於自己的事件佇列)中的事件。exec()在其內部不斷做著迴圈遍歷事件佇列的工作,呼叫qthread的quit()或exit()方法使退出執行緒,盡量不要使用terminate()退出執行緒,terminate()退出執行緒過於粗暴,造成資源不能釋放,甚至互斥鎖還處於加鎖狀態。
執行緒的同步:
1.同步基礎
臨界資源:每次只允許乙個執行緒進行訪問的資源
執行緒間互斥:多個執行緒在同一時刻都需要訪問臨界資源
執行緒鎖能夠保證臨界資源的安全性,通常,每個臨界資源需要乙個執行緒鎖進行保護。
執行緒死鎖:執行緒間相互等待臨界資源而造成彼此無法繼續執行。
產生死鎖的條件:
a、系統中存在多個臨界資源且臨界資源不可搶占
b、執行緒需要多個臨界資源才能繼續執行
死鎖的避免:
a、對使用的每個臨界資源都分配乙個唯一的序號
b、對每個臨界資源對應的執行緒鎖分配相應的序號
c、系統中的每個執行緒按照嚴格遞增的次序請求臨界資源
qmutex, qreadwritelock, qsemaphore, qwaitcondition 提供了執行緒同步的手段。使用執行緒的主要想法是希望它們可以盡可能併發執行,而一些關鍵點上線程之間需要停止或等待。例如,假如兩個執行緒試圖同時訪問同乙個全域性變數,結果可能不如所願。
2.互斥量qmutex
qmutex 提供相互排斥的鎖,或互斥量。在乙個時刻至多乙個執行緒擁有mutex,假如乙個執行緒試圖訪問已經被鎖定的mutex,那麼執行緒將休眠,直到擁有mutex的執行緒對此mutex解鎖。qmutex常用來保護共享資料訪問。qmutex類所以成員函式是執行緒安全的。
標頭檔案宣告: #include
互斥量宣告: qmutex m_mutex;
互斥量加鎖: m_mutex.lock();
互斥量解鎖: m_mutex.unlock();
如果對沒有加鎖的互斥量進行解鎖,結果是未定義的。互斥量的加鎖和解鎖必須在同一執行緒中成對出現。
qmutex ( recursionmode mode = nonrecursive )
qmutex有兩種模式:recursive, nonrecursive
a、recursive
乙個執行緒可以對mutex多次lock,直到相應次數的unlock呼叫後,mutex才真正被解鎖。
b、nonrecursive
預設模式,mutex只能被lock一次。
如果使用了mutex.lock()而沒有對應的使用mutex.unlcok()的話就會造成死鎖,其他的執行緒將永遠也得不到接觸mutex鎖住的共享資源的機會
bool trylock();
如果當前其他執行緒已對該mutex加鎖,則該呼叫會立即返回,而不被阻塞。
bool trylock(int timeout);
如果當前其他執行緒已對該mutex加鎖,則該呼叫會等待一段時間,直到超時
mythread.h
#ifndef mythread_h
#define mythread_h
#include #include class mythread : public qthread
;#endif // mythread_h
mythread.cpp
#include "mythread.h"
#include mythread::mythread(qobject *parent) :
qthread(parent)
void mythread::run()
}void mythread::startthread()
void mythread::stop()
Qt多執行緒開發 QThread
件 class mythread public qthread mythread virtual void run cpp檔案 void mythread run 件 class mythread public qthread mythread virtual void run class move...
QT中的執行緒QThread
譯文如下 class worker public qobject signals void resultready const qstring result class controller public qobject controller public slots void handleresu...
QThread多執行緒程式設計分析
傳統圖形介面應用程式都只有乙個執行緒執行,並且一次執行乙個操作。如果使用者呼叫乙個比較耗時的操作,就會凍結介面響應。乙個解決方法是按照事件處理的思路 呼叫 或來強迫事件迴圈進行,但是這種做法是有潛在風險的。按照 可能會引起遞迴,導致棧溢位崩潰的說法,當主線程在某個槽函式裡正在執行 processev...