2014-02-16 35 views
4

This article詳細介紹了「適當」使用的QThread的說使用運營商的「新」在QObject的構造函數(多線程)

順便說一句,這裏需要注意的一個非常重要的事情是,你不應該分配堆對象(在QObject類的構造函數中使用new),因爲此分配在主線程上執行,而不是在新的QThread實例上執行,這意味着新創建的對象將由主線程而不是QThread實例擁有。這會讓你的代碼無法工作。相反,在這種情況下,在process()這樣的主函數槽中分配這些資源,就像調用該對象時將在新線程實例上一樣,因此它將擁有該資源。

我明白了第一部分,分配堆對象(並因此運行構造函數)發生在創建QObject的線程中。只有在使用QThread :: moveToThread後,它纔會被推送到QThread。

不過我不太明白提到的所有權問題,尤其是

這意味着新創建的對象,然後由主線程所擁有

這當然指的不是標準的所有權因爲Qt中的資源很容易被父母子女機制所控制。

這是否意味着多線程的底層內存管理機制(或者QThread,儘管這只是OS'線程實現的包裝,據我所知)?如此,每個存儲資源的線程都有不同的「內存段/緩存」?

如果是這種情況,我可以看到問題,但我找不到完整的答案或解釋。謝謝!

回答

6

它指的是QObject生活在某些線程中的事實 - 默認情況下,創建它們的線程。 「Live」是指QObject不是可重入的也不是線程安全的:QObject只能從它所在的線程中使用。

雖然這個建議是錯誤的。這是完全安全的這樣

class Foo : public QObject { 
    Q_OBJECT 
    Foo() { 
     m_suboject = new Bar(this); 
     m_other = new Fie("/dev/blah", this); 
     ... 

的關鍵是在this參數,這意味着子對象正確父到富實例。因此,當你做

Foo *foo = new Foo; 
foo->moveToThread(thread); 

植根於「foo」的整個對象樹將被轉移到新的線程(moveToThread移動的對象及其所有子)。

+0

感謝您的澄清!現在對我來說更有意義。然而,我想,如果一個成員對象不能有父(即它不是一個QObject子類,像一些Qt的「原始」喜歡的QString類的),它是如何確保其對象是屬於一起移動?或者,也許這是一個非問題,因爲潛在的問題只與QObject相關? – Resurrection

+1

這通常不是問題 - 因爲與QObject不同,QString是可重入的:從多個線程使用它是安全的,但是一次只能從一個線程使用。 – peppe

+0

我明白了,我相信我完全理解這一點,謝謝你的時間! – Resurrection