**:
1. 不使用事件迴圈。這是官方的 manual 、example 以及相關書籍中都介紹的一種的方法。
a. 子類化 qthread2. 使用事件迴圈。(部落格 you are-doing-it-wrong 批駁的就是這種情況下的 一種用法。)b. 過載 run 函式,run函式內有乙個 while 或 for 的死迴圈
c. 設定乙個標記為來控制死迴圈的退出。
a. 子類化 qthread,在qt4.3(包括)之前,run 是虛函式,必須子類化qthread來實現run函式。b. 過載 run 使其呼叫 qthread::exec()
c. 並為該類定義訊號和槽,這樣一來,由於槽函式並不會在新開的 thread 執行,很多人為了解決這個問題在建構函式中呼叫
movetothread(this)而爭論和不解正是這樣的一條語句造成的。
bradley t. hughes 給出說明是: qthread 應該被看做是作業系統執行緒的介面或控制點,而不應該包含需要在新執行緒中執行的**。需要執行的**應該放到乙個qobject的子類中,然後將該子類的物件movetothread到新執行緒中。
而從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對照前面的定理,run函式中的**時確定無疑要在次執行緒中執行的,那麼其他的呢?比如 slot 是在次執行緒還是主線程中執行?public slots:
void slot()
signals:
void sig();
protected:
void run()
}; int main(int argc, char** argv)
你想說主線程,但又心有不甘,對麼?
涉及訊號槽,我們就躲不過 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 定時器停止執行.大概實...