std::condition_variable
とbool condition
を介してワーカースレッドの実行をトリガーしようとしています。作業者は通知を待ち、condition
が真であれば作業を開始します。作業後はcondition
がfalseに設定されます。さらに、同期するためのミューテックスがあります。他のスレッドでスレッド内に割り当てられていないものがあります
メインスレッドでは、ループがcondition
がfalseであるかどうかをチェックし、そうである場合はcondition
がtrueに設定され、condition_variableに通知されます。
出力が「スパム」は作業とを目が覚めただろうと、私は期待するこのコードを実行し、何とかthread_function()
でcondition
への割り当てがメインに表示されていないので、それは、一度だけ実行されますスレッド/はワーカースレッド内で失われます。代入の後、デバッガでそれを調べると、代入の後ではfalseになりますが、メインスレッドのifが評価されると、それは再び真です。
何か不足していますか?
私はこれをVS2013とVS2012で試しましたが、bool
をstd::atomic_bool
に置き換えようとしましたが、それでも役に立たなかったです。
#include <thread>
#include <mutex>
#include <condition_variable>
#include <iostream>
#include <atomic>
bool condition;
std::mutex condition_mutex;
std::condition_variable cv;
void thread_function() {
while (true) {
std::unique_lock<std::mutex> lock(condition_mutex);
cv.wait(lock);
std::cout << "woke up\n";
if (condition) {
// do stuff
std::cout << "thread working\n";
condition = false;
std::cout << "thread: " << (condition ? "true" : "false") << "\n";
}
}
}
int main() {
condition = false;
std::thread t(&thread_function);
while (true) {
std::unique_lock<std::mutex> lock(condition_mutex);
// std::cout << "main: " << (condition ? "true" : "false") << "\n";
if (!condition) {
condition = true;
cv.notify_one();
}
}
return 0;
}
cv.wait(ロック)で "偽の"起床が発生することがあります。つまり、notify_one()やnotify_all()によって引き起こされない起床です。 cv.wait()はmutexを待つのではなく、notify_one()またはnotify_all()を待ちます。スレッドセーフな内部動作と条件変数のチェックのためだけにmutexを使用します。とにかく、プログラム全体は意味をなさないが、それはどんな一時停止もせずにお互いに依存する2つの無限ループを持ち、いずれのループの内部でも行う。私は、これが実行されているCPUコアが実行中に100%であると推測します。 – BJovke
@BJovkeここであなたは絶対に正しいです、条件は、待機の前または後にチェックされないので、問題ありません。 –
@Alan Strokes待機後に状態がチェックされるため、偽の起床では問題は発生しません。 –