2013-10-15 29 views
4

我有一個3個QThreads通過相互調用(全部來自QThread的繼承。我知道有些人可能會建議使用moveToThread,但恰恰忽略了這一事實現在)。簡化代碼看起來如下:無法與成品()信號之間的QThread連接多個QThread的

線程1類:

void 
Thread1::run 
{ 
    // some execution 
    Thread2 t2 = new Thread2(); 
    connect(t2,SIGNAL(finished),this,SLOT(onFinished)); 
    t2->start(); 

    while(!stop) // stop was initialized as false 
    { 
     this->msleep(10); 
    }  
} 
void Thread1::onFinished(){ stop = true; } 

線程2類:

void 
Thread2::run 
{ 
    // some execution 
    Thread3 t3 = new Thread3(); 
    connect(t3,SIGNAL(finished),this,SLOT(onFinished)); 
    t3->start(); 

    while(!stop) // stop was initialized as false 
    { 
     this->msleep(10); 
    }  
} 
void Thread2::onFinished(){ stop = true; } 

Thread3類:

void 
Thread3::run 
{ 
    // some execution 
    QMutexLocker ml(&mMutex); 
} 

當我只有兩個線程,它的工作原理完美無瑕(例如,只有thread2和thread3)。在轉移到三線程場景後,onFinished()方法似乎不再正確地連接finished()信號。線程2中的onFinished()已被調用。我很確定thread3的執行已經完成。

誰能告訴我哪裏能有什麼錯呢?所有的

+0

我在您發佈的代碼部分沒有看到任何錯誤。嘗試使用'qDebug()'來查明'connect'是否返回true,並且實際調用了'onFinished()'槽。 –

+0

@TimMeyer,我在onFinished()上打印出來了,但是沒有打印出來。基本上程序一直卡在thread2的while循環中。但我很確定thread3已經完成了,因爲我在run()方法的末尾也有一個調試打印輸出。 –

回答

6

首先,你應該注意的是,默認的連接類型爲Qt::AutoConnection。這意味着如果信號是從接收對象的線程以外的其他線程發出的,則使用Qt::QueuedConnection。在這種情況下:The slot is invoked when control returns to the event loop of the receiver's thread. The slot is executed in the receiver's thread.所以你需要一個事件循環。

它與2個線程,因爲你可能有一個事件循環在你的主線程中運行。在你只用thread2thread3對象的情況下,thread2對象實際將在主線程,而thread3對象將生活在由thread2對象管理的線程。因此thread2對象的插槽應該可以工作。

但在3線的情況下,thread1對象將住在主線程,thread2對象將生活在thread1對象管理的線程,因爲沒有運行事件循環在那裏,在thread2對象插槽永遠被執行。

您可以在QThread::run()函數中調用QThread::exec()函數,但請注意,插槽將在您的QThread對象所在的線程中執行,而不是其管理的線程。因此,您不應使用QThread子類中的插槽。您應該創建一個QObject子類並將其移至一個線程。

另一種選擇是使用Qt::DirectConnection連接類型,當您將信號連接到插槽。

+0

感謝您的解釋! Qt :: DirectConnection似乎解決了這個問題。當你說「創建一個QObject子類並將其移動到一個線程」時,你是指使用moveToThread方法嗎?我可能會嘗試這種方法,因爲我正在修改onFinished()方法中的一些變量,所以我害怕Qt :: DirectConnection可能是一個問題? –

+0

@JohnYang是的,我是。在'Qt :: DirectConnection'的情況下,它就像直接函數調用一樣。 – thuga