執行緒雲集(一) QT執行緒

2021-10-09 00:25:25 字數 4518 閱讀 2011

目錄

1.1 qthread使用方法

1.2 qsemaphore使用方法

1.3 qwaitcondition使用方法

1.4 qthreadpool使用方法

1.5 qtconcurrent使用方法

前言:目前專案中使用到qsemaphore來構建執行緒池,之前只是簡單使用qthread類,這裡系統記錄多執行緒的基本使用,方便後面使用到的時候翻開回憶,不再到處搜尋知識點。

建立」乙個新執行緒,等待 cpu 來執行;當 cpu 來執行時,如果該執行緒需要等待另外某個事件被執行完後才能執行,那該執行緒此時是處於「阻塞」狀態;如果不需要等待其他事件,執行緒就可以被「執行」了,也可以稱為正在占用時間片;時間片用完後,執行緒會處於「就緒」狀態,等待下一次時間片的到來;所有任務都完成後,執行緒就會進入「退出」狀態,作業系統就會釋放該執行緒所分配的資源。

執行緒同步:所謂協同步調,即多個執行緒打配合完成某項複雜工作。執行緒同步涉及的技術有執行緒鎖(互斥物件mutex),條件變數(condition)和訊號量(semaphore)。

qt中提供了三種在主線程之外建立工作執行緒的方法:1. 繼承qthread;2.繼承qobject,然後使用movetothread(qthread * targetthread)將物件移動到工作執行緒中執行;3.繼承qrunnable,並將建立的物件移動到qthreadpool中進行執行。

qt官方建議僅僅在需要擴充套件qthread本身的功能時使用第一種方法,而執行一般的工作時可使用第2種或第3種方法。後兩者的區別是第2種方法可以通過訊號進行執行緒間的通訊。qrunnable沒有繼承qobject,適合執行不關心執行進度或者不需要在中間環節進行控制的方法

qthread

繼承qobject

.。它可以傳送started和finished訊號,也提供了一些slot函式。

qobject

可以用於多執行緒,可以傳送訊號呼叫存在於其他執行緒的slot函式,也可以postevent給其他執行緒中的物件。之所以可以這樣做,是因為每個執行緒都有自己的事件迴圈

qthread 的執行入口函式是run(),從該函式返回將結束執行緒;wait()函式是等待run()函式執行結束並返回,此時wait()返回值為true;建立執行緒的方法有兩種,1.直接繼承qthread; 2.使用qobject::movetothread()將 qobject 物件移到新開的 qthread 執行緒物件中,這樣 qobject 物件中所有的耗時操作都會在新執行緒中被執行。

class worker : public qobject

signals:

void resultready(const qstring &result);

}; class controller : public qobject

~controller()

public slots:

void handleresults(const qstring &);

signals:

void operate(const qstring &);

};

qthread的介面函式:

qthread(qobject* parent=0);new乙個qthread,父類有qthread的所有權,通過start()啟動執行緒

~qthread ()銷毀執行緒,在銷毀執行緒前等待finished()訊號

exit ( int returncode = 0 )告訴執行緒的事件迴圈通過返回碼離開,returncode=0表示success

isfinished()const,isrunning()const返回是否結束和是否執行

priority    priority () const返回執行緒執行的優先順序,如果執行緒沒執行返回7

setpriority ( priority priority )設定執行緒優先順序

setstacksize ( uint stacksize )設定最大執行緒堆疊,如果不設定由作業系統自動分配,且stacksize()返回0

wait( unsigned long time = ulong_max )如果是預設值則wait()將不會超時

void quit ()告訴執行緒的事件迴圈退出並且返回0值

void start ( priority priority = inheritpriority )以某種優先順序開啟乙個執行緒

void terminate ()終止當前執行緒。執行緒或許不會立即被終止,依賴於執行緒的排程策略

bool  isstopthread = false;

class athread:public qthread

void run()

if(keyevent->key () == qt::key_b)

//keypressevent (keyevent);

}

「程序的建立、撤銷與切換存在著較大的時空開銷」,因此出現了執行緒這種輕量級程序技術。如果還想進一步的降低系統資源開銷,人們想出了乙個辦法,就是讓執行完所有任務的執行緒不被銷毀,讓它處於「待命」的狀態等待新的耗時操作「進駐」進來。qt 提供了 qthreadpool 和 qrunnable 這兩個類來對執行緒進行重複的使用。使用的方法一般是將耗時操作放入qrunnable 類的 run() 函式中,然後整體把 qrunnable 物件扔到 qthreadpool 物件中就可以了。

qrunnalbe:能用到執行緒池的任務,基本上功能單一且並不需要和其他執行緒進行訊號槽的通訊

引用:

任務的統一封裝形式:qrunnable

qrunnable()

virtual ~qrunnable()

bool autodelete() const

void setautodelete(bool autodelete)

virtual void run() = 0

只需要繼承qrunnable並且重寫run函式,扔給執行緒池即可

class helloworldtask : public qrunnable}; 

helloworldtask *task = new helloworldtask();

qthreadpool::globalinstance->start(task);

qthreadpool只有執行緒qthread和任務qrunnable兩種資料容器來管理任務排程,執行緒池的本質就是協調兩種容器之間資料的互動。執行緒池中的執行緒也進行了二次封裝,由繼承於 qthread 的 qthreadpoolthread 類表示。該類在 qthread 的基礎上擴充套件了兩個私有變數:qrunnable * 和 qthreadpoolprivate *,乙個用於儲存當前執行緒要執行的任務,乙個用於儲存執行緒池的指標。

因為每個 qt 程式或者說每個程序都有乙個全域性 qthreadpool 物件,所以 globalinstance() 函式用於獲取該物件的指標,那麼用的時候直接用該靜態函式即可,顯式的建立乙個區域性執行緒池也是可以的。

};int main(int argc, char *ar**)

//顯示建立

}};int main(int argc, char *ar**)

return a.exec();

}

qthread 這種很底層的類,使用起來要考慮方方面面,用到底層的介面(如 qthread、訊號量、互斥鎖等),另外qt 提供了高階函式來簡化多執行緒編寫,qt concurrent 。

//pro 檔案新增「qt += concurrent」並且在我們的 h 檔案新增「#include 」

int main(int argc, char *ar**)

//傳參

extern void afunction(int arg1, double arg2, const qstring &string);

int a = 1;

double b = 2;

qstring string = "hello";

qtconcurrent::run(afunction, a, b, string);

//返回值

extern qstring function();

qfuturenfuture = qtconcurrent::run(function);

qstring result = future.result();

參考:

如何正確使用qthread  

QT執行緒(一) 執行緒類

執行緒之間共享資料,但又單獨執行 qt執行緒 qthread 是平台無關的 通常主線程從 main 開始執行,而在主線程中建立其他執行緒,其他執行緒派生於 qthread 1 執行緒優先順序總共8 個優先順序 執行緒優先順序從上到下越來越高。constant value description qt...

QT執行緒(一) 執行緒類

執行緒之間共享資料,但又單獨執行 qt執行緒qthread是平台無關的 通常主線程從main開始執行,而在主線程中建立其他執行緒,其他執行緒派生於qthread 1 執行緒優先順序 總共8個優先順序 執行緒優先順序從上到下越來越高。constant value description qthread...

細說qt多執行緒(一)

眾所周知,qt 建立多執行緒有主流的有3種方法 1.採用經典的qthread類。2.實現qrunable 介面。3.採用qt並行框架qtconcurrent。既然有三種方法,那麼哪種方式更好,在實際的專案中改採取哪種方式來實現?那麼我們不得不對3種方式做下對比。下面我將對每 一種方式,表達下我的淺見...