ibex
23rd December 2011, 16:11
I am working on some producer/consumer code using QtConcurrent as the producer. The consumer is running in the main GUI thread and I would like it to do something whenever some work is ready. I can use a QWaitCondition and get the producer tasks to call QWaitCondition::wakeOne() when finished but am having trouble exiting the loop when the QFuture reports finished:
Worker worker;
QFuture future=QtConcurrent::map(start, end, worker);
QMutex mutex;
QWaitCondition waitCondition;
mutex.lock();
while (true) {
if (results.ready())
processResults();
if (future.isFinished()) {
mutex.unlock();
break;
else if (waitCondition.wait(&mutex, timeout) {
break;//give up
}
}
Worker::operator() (int i) {
doWork(i);
waitCondition.wakeOne();
}
The trouble is the QFuture may finish between the calls to isFinished() and wait() resulting in a delay of 'timeout'. I would like the QFuture finishing to do a wakeOne() and have tried unsuccessfully using a direct connection to QFutureWatcher::finished(). I think the QFutureWatcher may depend on the event loop and as the consumer is in the main thread, it isn't received.
Would adding something like this be useful Qt enhancement to facilitate this:
QFuture::addFinishedCondition(QWaitCondition wc, bool wakeAll);
QFuture::addResultsReadyCondition(QWaitCondition wc, bool wakeAll);
Is there a solution using existing code?
thanks.
Worker worker;
QFuture future=QtConcurrent::map(start, end, worker);
QMutex mutex;
QWaitCondition waitCondition;
mutex.lock();
while (true) {
if (results.ready())
processResults();
if (future.isFinished()) {
mutex.unlock();
break;
else if (waitCondition.wait(&mutex, timeout) {
break;//give up
}
}
Worker::operator() (int i) {
doWork(i);
waitCondition.wakeOne();
}
The trouble is the QFuture may finish between the calls to isFinished() and wait() resulting in a delay of 'timeout'. I would like the QFuture finishing to do a wakeOne() and have tried unsuccessfully using a direct connection to QFutureWatcher::finished(). I think the QFutureWatcher may depend on the event loop and as the consumer is in the main thread, it isn't received.
Would adding something like this be useful Qt enhancement to facilitate this:
QFuture::addFinishedCondition(QWaitCondition wc, bool wakeAll);
QFuture::addResultsReadyCondition(QWaitCondition wc, bool wakeAll);
Is there a solution using existing code?
thanks.