2013-03-16 32 views
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(); 
} 

回答

1

QWaitCondition::wait的文檔指出:

互斥鎖必須是最初由調用線程鎖定

你應該從構造函數中刪除m->lock();並把它放在runMe()函數調用wait之前。