Concurrent Functions and Signals + Slots (Race Condition?)
-
So I have an asynchronous function that produces QFutureWatcher
results()
connected like so...
connect(watcherList.back(), &QFutureWatcherBase::finished, this, &MainWindow::resultsF);
This QtConcurrent::run() operation provides results that I want to use in another function.
*future = QtConcurrent::run(parameter1, parameter2, parameter3);
In aforementioned function I assign a value from QFutureWatcher
results()
.watcherList[i]->results().myResult
In this case, it's a subscript for a timer and passed as a value to extern function of QtConcurrent::run().
I am using a for() and if() statment to find out which of these asychronous operations have finished, with
isFinished()
method.for(int i = 0; i < watcherList.count(); i++){ if(watcherList[i]->isFinished()) { value1 = watcherList[i]->result().myValue; //later this is used by extern function with QtConcurrent::run() Timers[watcherList[i]->result().myValue]->setObjectName(QString::number(it)); Timers[watcherList[i]->result().myValue]->start(); break; } }
Problem: I am assigning 1 value (the same result) to 2 or more objects in extern function. (race conidtion?). isFinished() method doesn't seem to 'catch' that QFutureWatcher is tasked by
run()
later on, and is assigning the same results twice.So I have one value relating to 2 or more different Qt::Concurrent functions , as it appears that this function (using results()) is called again before run() has started.
I need a way to get where I only use one QFutureWatcher result that is finished, is run, and excluded from being used again until it is finished. On top of this, my aforementioned function (using the results) is connected to a signal from
QWebEnginePage::loadFinished();
So slot calls may be occurring within a small window of time (when two or more sites finish loading together). -
Hi,
In your loop, you always go through the whole list only checking for the elements to be in the finished state. Doing so, as long as you don't remove any element from the list, you will always stop at the first in that state.
It looks like a case where you should use the sender function to retrieve the watcher that has finished to continue your logic.
-
Hi,
In your loop, you always go through the whole list only checking for the elements to be in the finished state. Doing so, as long as you don't remove any element from the list, you will always stop at the first in that state.
It looks like a case where you should use the sender function to retrieve the watcher that has finished to continue your logic.
@SGaist Thank you. I didn't consider this. My mistake! Working much better now.
-