QT 多執行緒訊號與槽(二)

2021-09-25 23:50:24 字數 1877 閱讀 4991

在 qt 中我們應該要知道幾個問題。

物件依附於哪個執行緒

物件的依附性與槽函式執行的關係

物件的依附性是否可以改變,如何改變

預設情況下,物件依附於自身被建立的執行緒。

從**中發現,是主線程建立了 threadtest threada; 和 myclass my;這兩個物件,那麼這兩個物件就依附於主線程了

預設情況下,槽函式在物件所依附的執行緒中執行。

物件的依附性確實可以改變,從原始碼中我們可以找到這樣乙個玩意。

//在 qobject 中

void

movetothread

(qthread *thread)

;

該方法定義在了 qobject 中,通過這個方法可以改變物件的依附性。

試一下

#include

#include

#include

#include

class

myclass

:public qobject

public slots:

void

getstarted()

void

getfinished()

signals:};

class

threadtest

:public qthread

void

run(

) emit counter

(m_counter)

; m_counter = m_counter +1;

msleep

(200);

}}signals:

void

counter

(int n)

;void

counter_reset()

;public slots:

void

getcounter

(int n)

void

on_counter_reset()

};intmain

(int argc,

char

*ar**)

執行結果

從執行結果看,我們確實改變了物件的依附性。不過呢,給各位乙個提醒,我這裡使用的 qt 版本為5.10,如果你使用的 qt 版本低於 4.4 可是得不到我這個結果的哦,為什麼?

針對 4.4 及低於 4.4 的版本的 qt ,定義了訊號與槽,卻不能在子執行緒中呼叫槽函式。那是因為子執行緒沒開啟事件迴圈,這就涉及到訊號與槽的機制的原理了,畫了一張簡單的圖示,不會畫畫,湊合著看吧。。。。

我們傳送訊號後,訊號跑哪去了?訊號進入了事件佇列裡啦。但是只是進入到事件佇列卻不去處理的話並沒什麼卵用,這就好比顧客點了菜,卻沒有人告訴廚師要做什麼菜。呼叫 exec();開啟事件迴圈後就可以處理訊息佇列的訊息了。

訊號與槽需要事件迴圈來支援,因為 4.4 之後 run 預設呼叫 qthread::exec() ,開啟了事件迴圈,所以我們不主動在子執行緒中呼叫 exec()也能正常使用訊號與槽。在 4.4 之前(包括 4.4 )我們需要自己手動開啟事件迴圈,也就是呼叫 qthread::exec() ,這樣才能正常使用訊號與槽。

為什麼要改變物件的依附性?改變依附性有什麼意義嗎?

前面說到多執行緒的時候強調過,只要用到了多執行緒,就可能產生臨界資源競爭的情況。如果訊號的傳送和對應槽函式的執行在不同執行緒時,可能產生臨界資源的競爭。

QT 多執行緒訊號與槽(二)

乙個主線程,乙個次執行緒,主線程向次執行緒傳送訊號 mythread.h include include class mythread public qthread mythread.cpp include mythread.h include mythread mythread void myth...

QT 多執行緒訊號與槽(二)

乙個主線程,乙個次執行緒,主線程向次執行緒傳送訊號 mythread.h include include class mythread public qthread mythread.cpp include mythread.h include mythread mythread void myth...

qt 多執行緒 訊號槽

qt訊號多執行緒 當你connect的時候,型別為qt autoconnection就好了 如果slot在同一執行緒就是直接呼叫,如果slot在另外乙個執行緒就通過事件機制處理 在qt中,你的執行緒在呼叫exec函式後就進入了事件迴圈機制 這時,如果另外乙個執行緒傳送了乙個訊號過來 1 如果接收執行...