2

イベントからループを開始し、別のイベントからループを停止する必要があります。私の考えは、ボタンを押したときに関数 startDequeuing() を呼び出してループを開始し、関数 stopDequeuing() から "dequeuing" 変数を false にしてこのループを終了することでした。

スレッドを使用するのは初めてです。変数「デキュー」がロックされており、スレッドの外部からアクセスできないため、ループを開始するとプログラムがロックされます。正しいですか?

どうすればこの問題を解決できますか??

ここにいくつかのコードがあります:

void CameraManager::startDequeuing(){
    dequeuing = true;
    std::thread dequeueThread(&CameraManager::dequeueLoop, this);
    dequeueThread.join();
}

void CameraManager::stopDequeuing(){
    dequeuing = false;
}

void *CameraManager::dequeueLoop(){
    while(dequeuing){
        highSpeedCamera->dequeue();
        highSpeedCamera->enqueue();
    }
}
4

3 に答える 3

3

スレッドを使用することの要点は、複数の関数を並行して実行することです。ここ:

std::thread dequeueThread(&CameraManager::dequeueLoop, this);
dequeueThread.join();

2 番目のスレッドを開始し、最初のスレッドをスリープ状態にして、生成されたスレッドが戻るのを待ちます。したがって、実行中のスレッドは 1 つだけです。そのような種類の GUI イベント ループがある場合、そのイベント ループが空になるたびに呼び出されるコールバックを追加する可能性をロックする可能性があります。これにより、スレッドをまったく使用せずに、必要なことを実行できる場合があります。

解決策は次のようになります。

void CameraManager::startDequeuing(){
    dequeuing = true;
    dequeueThread = std::thread(&CameraManager::dequeueLoop, this);
}

void CameraManager::stopDequeuing(){
    {
        std::lock_guard<std::mutex> lock( mutex );
        dequeuing = false;
    }
    dequeueThread.join();
}

bool CameraManager::keepOnDequeuing()
{
    std::lock_guard<std::mutex> lock( mutex );
    return dequeuing;
}

void *CameraManager::dequeueLoop(){
    while( keepOnDequeuing() ){
        highSpeedCamera->dequeue();
        highSpeedCamera->enqueue();
    }
}
于 2012-08-17T14:50:11.473 に答える
3

join()スレッド関数が完了するまでブロックされるため、プログラムはデッドロックします。効果的に実行されているため、その時点で完了することはありませんwhile(true)

あなたdequeueThreadはあなたのクラスのメンバーになりたいです。の範囲だけ存続させたいのはなぜstartDequeuingですか?

于 2012-08-17T14:50:43.157 に答える
3

dequeingアトミック bool として定義:

#include <atomic>
std::atomic_bool dequeing = false;

ミューテックスを使用するよりもはるかに高速で、同じ同期が得られます。

于 2012-08-17T21:03:03.547 に答える