QEventLoop用于同步等待信号

时间:2014-01-28 20:47:30

标签: c++ multithreading qt

我正在使用Qt5,QCoreApplication。 为了允许可读且易于维护的代码,我需要在类/线程A中编写一个阻塞方法,它将发出一个信号,连接到另一个线程B中的一个槽,然后等待一个答案或一个超时在线程B中异步发生 我首先考虑的是一种自然的解决方案:让线程B回复连接到线程A中的插槽的信号,然后以某种方式等待它。似乎QEventLoop可以为我做到这一点。但我一直在阅读相互矛盾的陈述:这就是模式,但如果你可以避免它:-)。 我很确定我可以通过阻止B在准备就绪时释放的0 QSemaphore来实现我的目的。代码可能不会那么复杂。 Qt开发人员认为你有什么经历? 有没有一个好的解决方案,或者你在我的描述中发现了一些有缺陷的分析症状(即你认为我永远不需要做那样的事情吗?: - ))?

2 个答案:

答案 0 :(得分: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"

答案 1 :(得分:0)

如果你只是想在你的线程中发出一个信号,这意味着你的主线程将有一个插槽来连接线程信号,它很简单,只需发出它。 但是如果你想在你的线程中有一个插槽,并且在你的线程中接收信号等等,你必须在run方法中使用QEventloop。

通常,我只会使用QThread :: wait等待其他线程结束。

这里要小心,有些Qt对象无法像QSql *和QTcpSocket那样在线程上工作....