11

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()

4

2 に答える 2

13

http://doc.qt.io/qt-4.8/qfuturewatcher.html#setFutureから

信号の 1 つは、将来の現在の状態に対して発行される可能性があります。たとえば、未来がすでに停止している場合、終了したシグナルが発行されます。

言い換えると、 が呼び出されるQtConcurrent::run(...)前に完了した場合でも、 の現在の状態でシグナルを発行します。したがって、競合状態を回避するために何もする必要はありません。setFuturesetFutureQFuture

ただし、コードの残りの部分によっては、完了する前に, andが範囲外に出ないQFuture::waitForFinished()ようにするために呼び出す必要がある場合があります。MyClassQFutureQFutureWatcher QtConcurrent::run(...)

于 2012-09-21T08:50:28.793 に答える
0

私は単体テストでこれを切り取って実行していましたQSignalSpyが、からの信号を取得していませんでしたQFutureWatcherQCoreApplication::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);

シグナルはおそらくスレッドから発行され、この状況では、シグナルは直接実行されるのではなく、キューに入れられます。

于 2018-07-09T17:33:47.723 に答える