QThread 的使用方法

2021-08-31 23:33:30 字數 3072 閱讀 9311

**:

1. 不使用事件迴圈。這是官方的 manual 、example 以及相關書籍中都介紹的一種的方法。

a. 子類化 qthread

b. 過載 run 函式,run函式內有乙個 while 或 for 的死迴圈

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

2. 使用事件迴圈。(部落格 you are-doing-it-wrong 批駁的就是這種情況下的 一種用法。)

a. 子類化 qthread,

b. 過載 run 使其呼叫 qthread::exec() 

c. 並為該類定義訊號和槽,這樣一來,由於槽函式並不會在新開的 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 當初的設計導致的這種問題,而所有文件和例子中都沒有提到該如何使用qthread 進一步加劇了對qthread的這種誤用。

qthread 使用**

qthread 似乎是很難的乙個東西,特別是訊號和槽,有非常多的人(儘管使用者本人往往不知道)在用不恰當(甚至錯誤)的方式在使用 qthread,隨便用google一搜,就能搜出大量結果出來。無怪乎qt的開發人員 bradley t. hughes 聲嘶力竭地喊you are-doing-it-wrong。

和眾多使用者一樣,初次看到這個時,感到 bradley t. hughes有 些莫名奇妙,小題大作。儘管不舒服,當時還是整理過一篇部落格qthread 的使用方法

時間過去3個月,儘管依然沒怎麼用thread;但今天csdn論壇中有人問到這個問題,想想還是盡我所能整理一下吧。提公升自己,方便他人,何樂而不為呢?

run 函式是做什麼用的?manual中說的清楚:

原文如下(這段話我們稱為定理一吧):

這麼短的文字一眼就看完了,可是,這是什麼意思呢?又能說明什麼問題呢?看段簡單**:

class thread:public qthread 

public slots:

void slot()

signals:

void sig();

protected:

void run()

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

對照前面的定理,run函式中的**時確定無疑要在次執行緒中執行的,那麼其他的呢?比如 slot 是在次執行緒還是主線程中執行?

你想說主線程,但又心有不甘,對麼?

涉及訊號槽,我們就躲不過 connect 函式,只是這個函式大家太熟悉。我不好意思再用一堆廢話來描述它,但不說又不行,那麼折中一下,只看它的最後乙個引數吧(為了簡單起見,只看它最常用的3個值)

下面的列表,我們暫稱為定理二:

直接連線(direct connection)

佇列連線(queued connection)

同前面一樣,這些文字大家都能看懂。但含義呢?

不妨繼續拿前面的例子來看,slot 函式是在主線程還是次執行緒中執行呢?

定理二強調兩個概念:傳送訊號的執行緒接收者所依附的執行緒。而 slot 函式屬於我們在main中建立的物件 thread,即thread依附於主線程

太繞了?不是麼(要徹底理解這幾句話,你可能需要看qt meta-object系統和qt event系統)

如果上兩節看不懂,就記住下面的話吧(自己總結的,用詞上估計會不太準確)。

但上兩種解決方法都不好,因為qthread不是這麼用的(bradley t. hughes)

好了,不再新增更多文字了,看**,估計咱們都會輕鬆點

這是 qt manual 和 例子中普遍採用的方法。 但由於manual沒說槽函式是在主線程執行的,所以不少人都認為它應該是在次執行緒執行了。

/*!

* \file main.cpp**

*/ public slots:

void emitsig()

signals:

void sig();

};

class thread:public qthread

public slots:

void slot_main()

public slots:

void emitsig()

signals:

void sig();

};

class thread:public qthread

public slots:

void slot_thread()

public slots:

void emitsig()

signals:

void sig();

};

class object:public qobject

public slots:

void slot()

{ qdebug()<<"from thread slot:" 《結果:恩,slot確實不在主線程中執行(這麼簡單不值得歡呼麼?)

main thread: 0x1a5c

from thread slot: 0x186c

QThread 的使用方法

20101023更新 qthread 使用 qthread與qwidget的使用 起源 昨天不小心看到qt開發人員 bradley t.hughes blog中的一片文章 you are doing it wrong 結果看得頭昏腦脹 好歹也自學了近1年的qt,也一直很小心 很認真地閱讀qt和man...

QThread的正確使用方法

qt自帶的文件和例子中使用qthread都是繼承qthread,然後過載run,今天想在繼承自qthread類中自定義乙個槽,覺得對qthread的訊號 槽的機制在多執行緒的情況下有些不清楚的地方,猜想qthread的槽並不是執行在qthread例項建立的子執行緒中,但我需要讓槽執行在子執行緒中,查...

QThread和QTimer的使用方法

說明 1 一下小結不保證對,如果錯誤希望指正 2 queue和direc代表是的connect的鏈結方式,qt directconnection和qt queuedconnection 小結 我想實現的乙個小定時器程式 輸入s start 定時器啟動,列印資訊。輸入e end 定時器停止執行.大概實...