Qt兩種線程方式的實現與優缺點對比(及信號槽連接方式)

Qt的線程實現主要兩種方式:子類化QThread和對象moveToThread。

子類化QThread

實現方法:

  繼承QThread

  重寫run

  其它線程裏使用start函數來啓動此線程。

缺點

線程中的對象必須在run函數中創建。

線程無法接收信號,只能發送信號。

 

 對象moveToThread

實現方式:

新建類假設爲Worker,在類的槽函數裏實現邏輯,new一個QThread對象,並把Worker的實例化move到這個線程中去,連接好相應的信號和槽,在其它線程發射信號,此時槽函數會在線程裏執行。

 

優缺點:

優點是克服了重寫run的缺點,比較靈活簡潔,但是不能在線程裏面實現常駐任務(死循環的任務)。

 

輕量級的函數可以用movethread,無需創建獨立線程類,例如你有多個小函數要在線程內做, 全部扔給一個QThread。還有一開始沒使用線程,但是後邊發覺這些代碼還是放線程比較好,如果用子類化QThread的方法重新設計代碼,將會有可能讓你把這一段推到重來,這個時候,moveThread的好處就來了,你可以把這段代碼的從屬着movetothread,把代碼移到槽函數,用信號觸發它就行了。其它的話movetothread它的效果和子類化QThread的效果是一樣的,槽就相當於你的run()函數,你往run()裏塞什麼代碼,就可以往槽裏塞什麼代碼,子類化QThread的線程只可以有一個入口就是run(),而movetothread就有很多觸發的入口。

 

細節注意點:

moveToThread 只有槽函數纔會在新線程裏執行

該類new的時候不要指定父對象:否則移動失敗,提示 QObject::moveToThread: Cannot move objects with a parent。

 

總結     

1、常駐任務使用繼承QThread重寫run     2、其他的一次性任務或者間歇性任務儘量都用moveToThread

 

 

信號槽連接方式

使用moveToThread的方式需要注意下信號槽的連接方式,主要注意前三種的特點。

第一種Qt::AutoConnection是系統默認的連接方式。這種方式連接的時候,槽不是馬上被執行的,而是進入一個消息隊列,待到何時執行就不是我們可以知道的了,當信號和槽不是同個線程,會使用第三種QT::QueueConnection的鏈接方式。如果信號和槽是同個線程,調用第二種Qt::DirectConnection鏈接方式

 

第二種Qt::DirectConnection是直接連接,也就是只要信號發出直接就到槽去執行,無論槽函數所屬對象在哪個線程,槽函數都在發射信號的線程內執行,一旦使用這種連接,槽將會不在線程執行。

 

第三種Qt::QueuedConnection和第四種Qt::BlockingQueuedConnection是相似的,都是可以在不同進程之間進行連接的,不同的是,這裏第三種是在對象的當前線程中執行,並且是按照隊列順序執行。噹噹前線程停止,就會等待下一次啓動線程時再按隊列順序執行,等待QApplication::exec()或者線程的QThread::exec()才執行相應的槽,就是說:當控制權回到接受者所依附線程的事件循環時,槽函數被調用,而且槽函數在接收者所依附線程執行,使用這種連接,槽會在線程執行。如果沒有在新的線程裏,使用後,會放入消息隊列裏,等待exec。

 

第四種Qt::BlockingQueuedConnection是(必須信號和曹在不同線程中,否則直接產生死鎖)這個是完全同步隊列只有槽線程執行完纔會返回,否則發送線程也會等待,相當於是不同的線程可以同步起來執行。

 

第五種Qt::UniqueConnection跟默認工作方式相同,只是不能重複連接相同的信號和槽;因爲如果重複鏈接就會導致一個信號發出,對應槽函數就會執行多次。

 

第六種Qt::AutoCompatConnection是爲了連接QT4 到QT3的信號槽機制兼容方式,工作方式跟Qt::AutoConnection一樣。顯然這裏我們應該選擇第三種方式,我們不希望子線程沒結束主線程還要等,我們只是希望利用這個空閒時間去幹別的事情,當子線程執行完了,只要發消息給主線程就行了,到時候主線程會去響應。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章