1

複数のスレッドをqtと同期する際に問題があります(残念ながら3.3.8)。スレッドの開始は時間のかかる作業であるため、(ワーカー) スレッドを一度開始し、それを実行メソッドに保持して、新しい作業について通知したいと考えています。しかし、すべての作業が完了したら、呼び出しスレッドでこれらのワーカー スレッドを同期する必要もあります。

QThread のオーバーロードが正しい使い方ではないことはわかっていますが、Qt 3.3.8 には moveToThread-Method がないため、これを行う必要があります。

worker-thread-class は次のように定義されます (簡略化)。

class WorkerThread : public QThread
{
  private:
    QWaitCondition m_wcNewWork;
    QMutex m_mutexStopped;
    bool m_bStopped; /// Stop thread execution

    void run()
    {
        m_mutexStopped.lock();
        while(!m_bStopped)
        {
            m_mutexStopped.unlock();    
            m_wcNewWork.wait(); //wait for new work

            msleep(1000); // do something

            //>notify main thread that the work is done<

            m_mutexStopped.lock();
        }
        m_mutexStopped.unlock();    
    }
  public:
    WorkerThread() : m_bStopped(false) {}
    ~WorkerThread()
    {
        m_mutexStopped.lock();  
        m_bStopped = true;
        m_mutexStopped.unlock();    
        wait(); // Wait for thread

        //Cleanup       
    }
    void startProcessing()
    {
        m_wcNewWork.wakeOne(); /// Wakeup thread, since there is something to do        
    }        
}

これらのワーカー スレッドの束は、別のスレッドで作成されます。これをMainThreadと呼びましょう。ここで、すべてのワーカー スレッドが動作していることを MainThread に通知する必要があります。MainThread の WaitConditions は、WorkerThread ごとに 1 つずつ、問題を解決する可能性があると思いました。次に、メインスレッドで次のようなものを書きました

QWaitCondition waitWorkDone[numWorker];

//Start working
for (int i = 0; i < numWorker; i++)
{
    WorkerThread[i].setWaitCondition(waitWorkDone);
    WorkerThread[i].startProcessing();
}

//Wait for all workers to finish their work
for (int i = 0; i < numWorker; i++)
{
    waitWorkDone[i].wait();
}

WorkerThread::run-method では、 a を使用しwaitWorkDone.wakeOne()て MainThread に作業が完了したことを通知しました。残念ながら、これは機能しません。待機の前に waitWorkDone が起動されると、MainThread は永久に待機します。

質問は次のとおりです。実行メソッドを離れていないスレッドを同期するにはどうすればよいですか? Qt 4 ではスレッドプールを使用してこれを行うことができると思いますが、Qt 3 には存在しません。

前もって感謝します。

4

1 に答える 1

0

条件変数 (QWaitCondition) を間違った方法で使用しているようです。正しく機能させるには、ミューテックスでそれらを使用する必要があります。そうしないと、ここのように、ウェイク... 呼び出しが失われる可能性があります。それらを修正するか、(より簡単な方法で) セマフォを使用してワーカーを待つことができます。ワーカー スレッドは 1 回ずつ増分し、メイン スレッドは numWorker 回減分します。

「PThread Primer」ブックで条件変数に関するより良い説明を探すことができます (マルチスレッドの非常に良い入門書ですが、やや時代遅れです)。

于 2013-07-16T10:55:27.947 に答える