繁体   English   中英

如何在没有竞争条件的情况下将QFutureWatcher与QtConcurrent :: run()一起使用

[英]How can I use a QFutureWatcher with QtConcurrent::run() without a race condition

如果我正确理解了QFutureWatcher文档中的以下代码,那么最后一行之间存在竞争条件:

// Instantiate the objects and connect to the finished signal.
MyClass myObject;
QFutureWatcher<int> watcher;
connect(&watcher, SIGNAL(finished()), &myObject, SLOT(handleFinished()));

// Start the computation.
QFuture<int> future = QtConcurrent::run(...);
watcher.setFuture(future);

如果QtConcurrent::run(...)的函数...在调用下一行之前结束,那么将永远不会触发watcher.finished()信号。 我的假设是否正确? 我该如何解决这个bug?

来自http://doc.qt.io/qt-4.8/qfuturewatcher.html#setFuture

其中一个信号可能会针对未来的当前状态发出。 例如,如果未来已经停止,则将发出完成的信号。

换句话说,如果QtConcurrent::run(...)完成之前setFuture被调用, setFuture仍会发出上的当前状态的信号QFuture 因此,您不需要做任何事情以避免竞争条件。

但是,根据代码的其余部分,您可能需要调用QFuture::waitForFinished()以确保 QtConcurrent::run(...)完成之前MyClassQFutureQFutureWatcher不会超出范围。

我在单元测试中运行了这个QSignalSpyQSignalSpy没有从QFutureWatcher获取信号。 我通过在检查之前调用显式QCoreApplication::processEvents()解决了这个问题:

QFutureWatcher<int> watcher;
QSignalSpy spy(&watcher, &QFutureWatcher<int>::finished);

QFuture<int> future = QtConcurrent::run([](){
    qDebug() << "compute";
    return 42;
});
watcher.setFuture(future);
QCOMPARE(watcher.result(), 42);
QCOMPARE(spy.count(), 0);
QCoreApplication::processEvents();
QCOMPARE(spy.count(), 1);

信号可能是从线程发出的,在这种情况下,信号排队而不是直接执行。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM