QThread多執行緒程式設計分析

2021-09-23 01:36:21 字數 4086 閱讀 6949

傳統圖形介面應用程式都只有乙個執行緒執行,並且一次執行乙個操作。如果使用者呼叫乙個比較耗時的操作,就會凍結介面響應。乙個解決方法是按照事件處理的思路:呼叫

或來強迫事件迴圈進行,但是這種做法是有潛在風險的。 按照

可能會引起遞迴,導致棧溢位崩潰的說法,當主線程在某個槽函式裡正在執行

processevents

時,剛好有乙個能響應此槽函式的訊號傳送過(肯定是其他執行緒發的訊號),這時就可能會發生可怕的遞迴,導致棧溢位崩潰。原因是

processevents

在處理自己槽函式的事件時,又會呼叫到

processevents

,進入到無盡的遞迴中。

另外乙個解決方法是:採用多執行緒。

qt qthread

多執行緒程式設計的方法一直有個爭議,就是

bradley t. hughes

:you

』re doing it wrong

歸納為3

中方法優劣問題:

不使用事件迴圈。這是官方的

manual

、example

以及相關書籍中都介紹的一種的方法。

子類化qthread;過載

run

函式,run

函式內有乙個

while

或for

的死迴圈;

設定乙個標記為來控制死迴圈的退出。

這種方法也是

bradley t. hughes

極力批判的。

子類化qthread;過載

run

使其呼叫

qthread::exec()

;並為該類定義訊號和槽,這樣一來,由於槽函式並不會在新開的

thread

執行,很多人為了解決這個問題在建構函式中呼叫

movetothread(this);

而爭論和不解正是這樣的一條語句造成的。

bradley t. hughes

給出說明是:

qthread

應該被看做是作業系統執行緒的介面或控制點,而不應該包含需要在新執行緒中執行的**。需要執行的**應該放到乙個

qobject

的子類中,然後將該子類的物件

movetothread

到新執行緒中。

在qt4.3(包括)

之前,run

是虛函式,必須子類化

qthread

來實現run

函式。而從

qt4.4

開始,qthreads-no-longer-abstract

,run

預設呼叫

qthread::exec()

。這樣一來不需要子類化

qthread

了,只需要子類化乙個

qobject

就夠了,這正是被

bradley t. hughes

推薦的方法。

類似於:

qthread thread;

object obj;

dummy dummy;

obj.movetothread(&thread);

qobject::connect(&dummy, signal(sig()), &obj, slot(slot()));

thread.start();

回到問題的本質,我們想要新開乙個子執行緒來完成耗時的操作,有兩個地方可以實現: (

1)子類化

qthread

的run()

函式裡,在

run()

函式裡執行耗時的操作。因為

run()

函式是子執行緒的入口函式,一定不和主線程在同乙個執行緒。就是方法

1介紹的。如果在

qthread

子類裡的

slot

裡執行耗時操作,因為

slot

是在主線程中執行的,所以行不通。 (

2)利用方法(

3),子類化

qobject ,

如object

。在object

的slot

裡執行耗時操作。但是

slot

仍在主線程裡執行,怎麼辦?

qthread *thread

;object.movetothread(thread);

這樣,這個

qobject

的slot

都會在子執行緒裡執行,達到了和主線程區分開的目的啦。

所以,方法(

1)和方法(

3)是正確的

qt qthread

多執行緒程式設計方法,方法(

2)用的最多,但只是三人成虎,一種不恰當的用法。下面給出方法(

1)和方法(

3)的**片段,各種思路請慢慢斟酌。

主線程開兩個子執行緒,子執行緒a列印

a,子執行緒b列印

b,通過乙個

dialog

控制。

(1)thread.h:

#ifndef thread_h

#define thread_h

#include

class thread : public qthread ;

#endif

(2)threaddialog.h:

#ifndef threaddialog_h

#define threaddialog_h

#include

#include "thread.h"

class qpushbutton;

class threaddialog : public qdialog ;

#endif

(3)thread.cpp

#include

#include

#include "thread.h"

thread::thread()

void thread::setmessage(const qstring &message)

void thread::run()

void thread::stop()

(4)threaddialog.cpp

#include

#include "threaddialog.h"

threaddialog::threaddialog(qwidget *parent)

: qdialog(parent)

void threaddialog::startorstopthreada()

else }

void threaddialog::startorstopthreadb()

else }

void threaddialog::closeevent(qcloseevent *event)

(5)main()

#include "threaddialog.h"

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

測試結果:

結果:slot

確實不在主線程中執行。

main thread: 0x1a5c

from thread slot: 0x186c

其他

QThread多執行緒程式設計經典案例分析

傳統的圖形介面應用程式都只有乙個執行緒執行,並且一次執行乙個操作。如果使用者呼叫乙個比較耗時的操作,就會凍結介面響應。乙個解決方法是按照事件處理的思路 另外乙個解決方法是 採用多執行緒。qt qthread多執行緒程式設計的方法一直有個爭議,就是bradley t.hughes you re doi...

QThread多執行緒程式設計經典案例分析

傳統的圖形介面應用程式都只有乙個執行緒執行,並且一次執行乙個操作。如果使用者呼叫乙個比較耗時的操作,就會凍結介面響應。乙個解決方法是按照事件處理的思路 另外乙個解決方法是 採用多執行緒。qt qthread多執行緒程式設計的方法一直有個爭議,就是bradley t.hughes you re doi...

Qt多執行緒開發 QThread

件 class mythread public qthread mythread virtual void run cpp檔案 void mythread run 件 class mythread public qthread mythread virtual void run class move...