我用的是Qt5,QCoreApplication。为了实现代码的可读性和易维护性,我需要在类/线程A中编写一个阻塞方法,它将发出一个连接到不同线程B中的槽的信号,然后等待应答或超时在线程B中异步发生。我首先考虑的是一种自然的解决方案:让线程B回复连接到线程A中的槽的信号,然后以某种方式等待它。看起来QEventLoop可以帮我做到这一点。但我一直在阅读相互矛盾的声明:这就是模式,但如果可以的话,请避免:-)。我非常确定我可以通过在0 QSemaphore上阻塞A来实现我的目的,B会在准备好的时候释放它。通过这种方式,代码可能不会太复杂。你有经验的Qt开发人员怎么想?有没有一个好的解决方案,或者你在我的描述中发现了一些有缺陷的分析的症状(例如,你认为我永远不应该做这样的事情吗?:-)?
发布于 2014-01-29 05:17:51
您可以利用的关键要素是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"发布于 2014-01-29 05:03:01
如果你只是想在你的线程中发出一个信号,这意味着你的主线程将有一个插槽来连接你的线程信号,这很简单,只需发出它。但是如果你想在你的线程中有一个槽,并且在你的线程中接收信号之类的东西,你必须在你的run方法中使用QEventloop。
通常,我只会使用QThread::wait来等待其他线程结束。
这里要小心,一些Qt对象不能跨线程工作,比如QSql*和QTcpSocket……
https://stackoverflow.com/questions/21416487
复制相似问题