2014-01-28 126 views
1

我正在使用Qt5,QCoreApplication。 爲了保持代碼的可讀性和易維護性,我需要在類/線程A中編寫一個阻塞方法,該方法將發出一個信號,連接到不同線程B中的一個插槽,然後等待答案或在線程B中異步發生超時。 我首先想到了什麼感覺就像是一個自然的解決方案:讓線程B回覆連接到線程A中的插槽的信號,並以某種方式等待它。看來QEventLoop可以爲我做到這一點。但我一直在讀相互矛盾的陳述:這就是模式,但是如果你能:-),就避免它。 我很確定我可以通過阻塞A上的一個0 QSemaphore來實現我的目的,B準備就緒時會釋放它。代碼可能不會那麼複雜。 你曾經歷過什麼Qt開發人員的想法? 有沒有一個好的解決方案,或者你在我的描述中發現了一些有缺陷的分析症狀(即你認爲我永遠不需要做那樣的事情:-))?QEventLoop用於同步等待信號

回答

0

如果你只是想在你的線程發出一個信號,這意味着你的主線程將有一個插槽來連接你的線程信號,這很簡單,只是發射它。 但是如果你想在你的線程中有一個插槽,並且在你的線程中接收到信號等等,你必須在你的運行方法中使用QEventloop。

通常,我會用QThread :: wait等待其他線程結束。

這裏要小心,一些Qt的對象不能跨線程像QSQL *和工作與QTcpSocket ....

2

,你可以利用的主要成分是Qt::BlockingQueuedConnection

此連接類型可以讓您從插槽傳遞返回值。您可以在信號插槽連接中使用它。您也可以直接調用該插槽而不使用通過QMetaMethod::invoke/QMetaObject::invokeMethod機制的信號。

#include <QDebug> 
#include <QThread> 
#include <QCoreApplication> 

class Master : public QObject { 
    Q_OBJECT 
public: 
    Q_SIGNAL bool mySignal(); 
    Q_SLOT void process() { 
    if (mySignal()) { // this can be a blocking call 
     qDebug() << "success!"; 
    } 
    thread()->quit(); 
    } 
}; 

class Slave : public QObject { 
    Q_OBJECT 
public: 
    Q_SLOT bool mySlot() { 
    // do whatever processing is needed here 
    // It's OK to call QCoreApplication::processEvents here 
    return true; 
    } 
}; 

int main(int argc, char** argv) { 
    QCoreApplication app(argc, argv); 
    QThread masterThread, slaveThread; 
    Master master; 
    Slave slave; 
    master.moveToThread(&masterThread); 
    slave.moveToThread(&slaveThread); 
    slave.connect(&master, SIGNAL(mySignal()), SLOT(mySlot()), 
       Qt::BlockingQueuedConnection); 
    masterThread.start(); 
    slaveThread.start(); 
    QMetaObject::invokeMethod(&master, "process"); 
    masterThread.wait(); 
    slaveThread.quit(); 
    slaveThread.wait(); 
    return 0; 
} 

#include "main.moc" 
+0

非常感謝!我不知道Qt :: BlockingQueuedConnection返回值。我似乎無法在官方Qt文檔中找到它。我錯過了嗎?但它並沒有解決我的問題,因爲我的線程B不能同步產生答案。經過一夜的睡眠,我想我會去線程B(我的主線程)的狀態機。線程適用於不能編程狀態機的人,對吧?不過,如果我只有更多的聲望,我還是會投票贊成你的回答。乾杯。 – nilo

+0

@nilo阻塞排隊連接肯定記錄在案。只要查看「連接」參數。 –

+0

@nilo我不明白你的意思,奴隸線程不能同步產生答案。一個線程必須在控制之下,而另一個線程是從屬的。從屬線程上的調用是完全同步的 - 只有當控制軌跡在該線程的事件循環中時纔會發生(因此線程不忙於其他任何事情),並且僅在主線程被阻塞並等待結果時纔會發生。 –