Qt多執行緒學習 二 使用QObject

2021-08-13 10:53:40 字數 4126 閱讀 7092

總結參考鏈結

2018.1.26補充:在學習了繼承使用qobject來實現多執行緒之後,一直頻繁的使用,在這過程中,經常遇到這個問題:在主線程中建立多執行緒,然後主線程假死。

qobjectqt框架的基本類,但凡涉及到訊號與槽有關的類都是繼承於qobjectqobject提供了qt關鍵技術訊號與槽的支援以及事件系統的支援,同時它提供了執行緒操作的介面,也就是qobject可以選擇在不同的執行緒中執行。

qobject的執行緒轉移函式是:void movetothread(qthread* targetthread),通過此函式可以把乙個頂層object(就是沒有父級)轉移到乙個新的執行緒中。

qobject來實現多執行緒預設支援事件迴圈(qt的許多非gui類也需要事件迴圈支援,如qtimerqtcpsocket),qthread要支援事件迴圈需要在qthread::run()中呼叫qthread::exec(),否則那些需要事件迴圈支援的類都不能正常傳送訊號,因此如果要使用訊號與槽,直接使用qobject來實現多執行緒。

qobject的執行緒轉移函式:void movetothread(qthread* targetthread),通過此函式可以把乙個頂層qobject轉移到乙個新執行緒裡。

qthread自身並不生存在它run函式所在的執行緒,而是生存在舊的執行緒中。

使用qobject建立多執行緒的方法如下:

#ifndef threadobject_h

#define threadobject_h

#include

#include

class threadobject : public qobject

;#endif // threadobject_h

#include "threadobject.h"

#include

#include

#include

#include

#include

#include

threadobject::threadobject(qobject *parent):qobject(parent)

,m_runcount(10)

,m_runcount2(std::numeric_limits::max())

,m_isstop(true)

threadobject::~threadobject()

void threadobject::setruncount(int

count)

void threadobject::runsomebigwork1()

intcount = 0;

qstring str = qstring("%1->%2,thread id:%3").arg(__file__).arg(__function__).arg(*(int*)qthread::currentthreadid());

emit message(str);

int process = 0;

while(1)

if(m_runcount == count)

sleep(1);

int pro = ((float)count / m_runcount) * 100;

if(pro != process)

++count;

}}void threadobject::runsomebigwork2()

intcount = 0;

qstring str = qstring("%1->%2,thread id:%3").arg(__file__).arg(__function__).arg(*(int*)qthread::currentthreadid());

emit message(str);

int process = 0;

qelapsedtimer timer;

timer.start();

while(1)

if(m_runcount2 == count)

int pro = ((float)count / m_runcount2) * 100;

if(pro != process)

++count;

}}void threadobject::stop()

可以知道,在這個繼承oobject的類中,並沒有繼承和執行緒相關的東西,只是乙個普通的類而已。但是通過movetothread,這個類的功能就在乙個執行緒中執行了。

void widget::startobjthread()

m_objthread =

new qthread(); // deletelater make thread kill itself

m_obj =

new threadobject(); // new thread inherit from qobject, without parent object

m_obj->movetothread(m_objthread);

connect(m_objthread, &qthread::finished, m_objthread, &qobject::deletelater);

connect(m_objthread, &qthread::finished, m_obj, &qobject::deletelater);

connect(this, &widget::startobjthreadwork1, m_obj, &threadobject::runsomebigwork1);

connect(this, &widget::startobjthreadwork2, m_obj, &threadobject::runsomebigwork2);

connect(m_obj, &threadobject::progress, this, &widget::progress);

connect(m_obj, &threadobject::message, this, &widget::receivemessage);

m_objthread->start();

}

這個函式在某個槽中被呼叫,然後按照這個流程即可建立乙個繼承qobject的執行緒。主要就是

m_objthread =

new qthread(); // deletelater make thread kill itself

m_obj =

new threadobject(); // new thread inherit from qobject, without parent object

m_obj->movetothread(m_objthread);

connect(m_objthread, &qthread::finished, m_objthread, &qobject::deletelater);

connect(m_objthread, &qthread::finished, m_obj, &qobject::deletelater);

使用qthread需要呼叫qthread::exec(),否則那些需要事件迴圈支援的類都不能正常傳送訊號,因此如果要使用訊號與槽,直接使用qobject來實現多執行緒。

qt使用多執行緒的一些心得——1.繼承qthread的多執行緒使用方法

qthread詳解

Qt多執行緒(二)

1 新建工程後,新增執行緒類mythread,基類為qobject ifndef mythread h define mythread h include class mythread public qobject endif mythread h include mythread.h includ...

Qt 多執行緒學習

最開始作為入門我也想用比較普遍的方法 繼承qthread並且重寫 void run 函式。這個方法其實挺簡單的,就是自己寫乙個mythread類繼承qthread,比如說 ifndef mythread h define mythread h include include class mythre...

Qt學習(二) 多執行緒控制

執行緒之間存在著相互制約的關係,具體可分為互斥和同步這兩種關係。在程式中,通常都會用到叫做 臨界資源 的東西,可能是一塊記憶體,乙個資料結構,乙個檔案等具有排他性使用的東西。這些東西,在多執行緒環境下,必須進行互斥處理,才能安全地使用臨界資源。所以,對臨界資源執行互斥操作的 片段,叫做臨界區。互斥量...