I am having some trouble resolving a race condition that arises when acquiring a lock. I have a large computation that is triggered asynchronously. I need my previous synchronous task to end before the large task begins. The large task launches and waits on a condition variable and, in an ideal world, the small tasks will notify the condition variable when they are done. My problem comes from the large task starting too soon, and the small tasks trigger a condition variable that has yet to full initialize and thus does not actually trigger, causing the program to be locked.

I have boiled it down to this minimal example.

I would assume this is a common problem. How can I check that my condition variable has actually got hold of a mutex and is locked?

#include <QCoreApplication>
#include <QObject>
#include <QFuture>
#include <QtConcurrent/QtConcurrent>
#include <QFutureWatcher>
#include <QWaitCondition>

class workUnit: public QObject
{
    Q_OBJECT

    public:
    workUnit(QObject *parent)
    {
        m = new QMutex();
        m->lock();
        w=new QWaitCondition();
    }
    QWaitCondition* w;
    QMutex* m;

public slots:
    void runMe()
    {
        w->wait(m);
        m->unlock();
        //perform long computation
    }
};


int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    workUnit* mUnit=new workUnit(&a);
    QFutureWatcher<void> w;
    QObject::connect(&w, SIGNAL(finished()), &a, SLOT(quit()));
    QFuture<void> f = QtConcurrent::run(mUnit,&workUnit::runMe);
    w.setFuture(f);
    _sleep(1000);//with this delay it works, without the delay it doesn't
    mUnit->w->wakeAll();//This would be triggered by another process
    return a.exec();
}
有帮助吗?

解决方案

The documentation for QWaitCondition::wait states that:

The mutex must be initially locked by the calling thread.

You should remove m->lock(); from the constructor and put it in the runMe() function before the call to wait.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top