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 に答える