我正在使用 Qt5、QCoreApplication。 为了使代码可读且易于维护,我需要在类/线程 A 中编写一个阻塞方法,该方法将发出信号,连接到不同线程 B 中的插槽,然后等待应答或超时在线程 B 中异步发生。 我首先考虑的是一个自然的解决方案:让线程 B 用连接到线程 A 中的插槽的信号进行回复,并以某种方式等待它。看来 QEventLoop 可以为我做到这一点。但我一直在阅读矛盾的陈述:这就是模式,但如果可以的话,请避免它:-)。 我很确定我可以通过在 0 QSemaphore 上阻止 A 来实现我的目的,而 B 在准备好时会释放该 QSemaphore。这样代码可能不会更复杂。 经验丰富的 Qt 开发人员有何看法? 有没有一个好的解决方案,或者您在我的描述中发现了一些有缺陷的分析症状(即您认为我永远不需要做这样的事情吗?:-))?
最佳答案
您可以利用的关键要素是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"
关于c++ - QEventLoop 用于同步等待信号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21416487/