1

我在解决获取锁时出现的竞争条件时遇到了一些麻烦。我有一个异步触发的大型计算。我需要在大型任务开始之前结束我之前的同步任务。大任务启动并等待条件变量,在理想情况下,小任务将在完成时通知条件变量。我的问题来自于大任务启动得太早,小任务触发了一个尚未完全初始化的条件变量,因此实际上并没有触发,导致程序被锁定。

我把它归结为这个最小的例子。

我认为这是一个常见问题。如何检查我的条件变量是否实际上已获得互斥锁并被锁定?

#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();
}
4

1 回答 1

1

的文档QWaitCondition::wait指出:

互斥锁最初必须由调用线程锁定。

您应该m->lock();从构造函数中删除并将其放入runMe()函数中,然后再调用wait.

于 2013-03-16T22:58:13.263 回答