UIスレッド&ワーカースレッド間のデータトランザクションにC++11
のstd::condition_variableを使用しようとしています。C++:UIスレッドとワーカーstd :: threadの間でstd :: condition_variableを使用する方法
状況:
m_calculated_value
は複雑なロジックの後に算出した値です。これは、UIスレッドからのイベントのトリガーで必要です。 UIスレッドは、を呼び出して、という値を取得します。この値は、ワーカースレッド関数MyClass::ThreadFunctionToCalculateValue
によって計算される必要があります。
コード:
std::mutex m_mutex;
std::condition_variable m_my_condition_variable;
bool m_value_ready;
unsigned int m_calculated_value;
// Gets called from UI thread
unsigned int MyClass::GetCalculatedValue() {
std::unique_lock<std::mutex> lock(m_mutex);
m_value_ready = false;
m_my_condition_variable.wait(lock, std::bind(&MyClass::IsValueReady, this));
return m_calculated_value;
}
bool MyClass::IsValueReady() {
return m_value_ready;
}
// Gets called from an std::thread or worker thread
void MyClass::ThreadFunctionToCalculateValue() {
std::unique_lock<std::mutex> lock(m_mutex);
m_calculated_value = ComplexLogicToCalculateValue();
m_value_ready = true;
m_my_condition_variable.notify_one();
}
問題:
しかし、問題はm_my_condition_variable.wait
は決して戻らないということです。
質問:
は、私がここで間違って何をしているのですか?
ワーカースレッドからの条件変数信号でUIスレッドが待機する正しい方法はありますか? condition_variableがワーカースレッド関数のエラーのために決してトリガしない状況からどうやって抜け出すのですか?何とかここでタイムアウトを使用できる方法はありますか?
は、それがどのように動作するかを理解しようとすると:
ループがcondition_var.wait
周りブール変数の状態を確認しながら、私は、彼らがを使用する多くの例で参照してください。変数の周りのループのポイントとは何ですか? 他のスレッドからnotify_one
を呼び出すと、m_my_condition_variable
はwait
から戻ると思いますか?
あなたが参照している例は、述語と待機() ''のオーバーロードを使用していませんでした。したがって、彼らは基本的にそれらを再実装しました。それにもかかわらず、あなたのユースケースでは、条件変数ではなく将来を使うべきです。 – Ext3h
'MyClass :: GetCalculatedValue'が返ってきたら、必要な値を準備するために' m_calculated_value'が必要です。これは、データが準備完了であることを伝えるために、スレッド間のシグナリングの典型的なケースのように思えます。 @ Wxt3hあなたもそうだと思いませんか?将来はどのようにここで助けますか?もう少し詳しく教えていただけますか? –
私は間違っていますが、あなたの症状を引き起こすものは何もありません。あなたは複数の質問をし、[mcve]を提供しません。状態変数をどのようにusrにするかをカバーするSOのQ&Aがあります。私はそれらを読んでアドバイスし、彼らの言うことをお勧めします。 – Yakk