同時シミュレータで実行された2スレッドのうち1スレッドを条件が発生するまで待ちたいのですが、シミュレータでプログラムを1000回以上実行した後に条件が発生した可能性があります。条件が発生した後、待機スレッドが再度実行されました。どうすればいいですか?
4 に答える
条件変数が必要です。
コンパイラがC++11によって導入されたものをサポートしている場合std::conditional
は、詳細を確認できます。
コンパイラがそれをサポートしておらず、win32スレッドを使用している場合は、次を参照してください。
そして、ここに完全な例があります。
また、POSIXスレッドを使用している場合は、次を参照してください。
conditional_variable
ここでwin32プリミティブを使用した私の実装を見ることができます:
下にスクロールして、最初にその実装を確認してから、並行キューの実装での使用法を確認してください。
条件変数の一般的な使用法は次のとおりです。
//lock the mutex first!
scoped_lock myLock(myMutex);
//wait till a condition is met
myConditionalVariable.wait(myLock, CheckCondition);
//Execute this code only if the condition is met
ここCheckCondition
で、は条件をチェックする関数(またはファンクター)です。誤っwait()
てウェイクアップしたときに関数によって内部的に呼び出され、条件がまだ満たされていない場合、関数は再びスリープします。スリープ状態になる前に、アトミックにミューテックスを解放します。wait()
wait()
C ++ 11がなくても、POSIXスレッドをサポートするシステムがある場合は、条件変数を使用できます。他の選択肢もありますが、問題の説明方法を考えると、条件変数が最も簡単な場合があります。
pthread条件変数は、ミューテックスと組み合わせて使用されます。条件変数の秘訣は、それを待機すると、待機呼び出しが戻るまで、取得したミューテックスが解放され、その時点でミューテックスが再度取得されることです。シーケンスは次のとおりです。
- ミューテックスを取得
- PREDICATEは真ではありませんが
- 条件変数を待つ
- クリティカルセクションで作業する
- PREDICATEがtrueの場合
- 信号条件変数
- ミューテックスをリリース
シグナルステップは、複数のスレッドが上記の同じクリティカルセクションに入る場合に使用されます。
別のスレッドが同じミューテックスにアクセスして、PREDICATEに影響を与える状態を変更する可能性がある場合、そのスレッドは、誰かにシグナルを送信する必要があるかどうかを確認する必要があります。
- ミューテックスを取得
- クリティカルセクションで作業する
- PREDICATEがtrueの場合
- 信号条件変数
- ミューテックスをリリース
対象となるPOSIXコマンドは次のとおりです。
pthread_mutex_init()
pthread_mutex_destroy()
pthread_mutex_lock()
pthread_mutex_unlock()
pthread_cond_init()
pthread_cond_destroy()
pthread_cond_wait()
pthread_cond_signal()
シグナリングにセマフォを使用する。以下の例(アプリケーションクリーン出口):
ヘッダーで宣言する
static sem_t semPrepareExit; //declaration
ソース内(メインスレッド);
sem_init(&semPrepareExit, 0, 0); ///semaphore initialized
...
///now wait for the signal on the semaphore, to proceed hereforth
sem_post(&semPrepareExit);
/// cleanup ahead
...
ソースでは、(スポーンスレッド);
...
sem_post(&semPrepareExit);
これで、「sem_post」を使用してセマフォで信号を送るとすぐに。メインスレッドは待機ノード/ポイントでシグナルを受信し、それ以降に進みます。
このようなものを試してください:
class CmyClass
{
boost::mutex mtxEventWait;
bool WaitForEvent(long milliseconds);
boost::condition cndSignalEvent;
};
bool CmyClass::WaitForEvent(long milliseconds)
{
boost::mutex::scoped_lock mtxWaitLock(mtxEventWait);
boost::posix_time::time_duration wait_duration = boost::posix_time::milliseconds(milliseconds);
boost::system_time const timeout=boost::get_system_time()+wait_duration;
return cndSignalEvent.timed_wait(mtxEventWait,timeout); // wait until signal Event
}
//待機するために、WaitForEventメソッドを呼び出します
WaitForEvent(1000); // it will timeout after 1 second
//これは、イベントを通知する方法です。
cndSignalEvent.notify_one();