cbreak と Ravadre (コメント) の助けを借りて、私はここから得ました:
int main()
{
std::mutex m;
std::condition_variable cv;
std::thread t([&] {
std::this_thread::sleep_for(std::chrono::seconds(1));
std::unique_lock<std::mutex> lock(m);
cv.wait(lock);
std::cout << "Yay!\n";
});
cv.notify_one();
t.join();
}
ここまでは、通常はまったく終了しません。
int main()
{
std::mutex m;
std::condition_variable cv;
bool flag = false;
std::thread t([&] {
std::this_thread::sleep_for(std::chrono::seconds(1));
std::unique_lock<std::mutex> lock(m);
cv.wait(lock, [&] { return flag; });
std::cout << "Yay!\n";
});
{
std::lock_guard<std::mutex> lock(m);
flag = true;
}
cv.notify_one();
t.join();
}
これは実際に仕事をしますが、それでも多くの不必要なオーバーヘッドのようです。同等の、よりパフォーマンスの高い(またはよりエレガントな)回答を自由に投稿してください。喜んで受け入れます。ただし、標準 C++11 のみを使用してください。そうでない場合は、標準 C++11 でこれができない理由を説明してください。
編集:これをカプセル化するためのクラスsafe_flagも作成しました(cbreakに感謝します)。改善点があれば遠慮なく提案してください。
class safe_flag
{
mutable std::mutex m_;
mutable std::condition_variable cv_;
bool flag_;
public:
safe_flag()
: flag_(false)
{}
bool is_set() const
{
std::lock_guard<std::mutex> lock(m_);
return flag_;
}
void set()
{
{
std::lock_guard<std::mutex> lock(m_);
flag_ = true;
}
cv_.notify_all();
}
void reset()
{
{
std::lock_guard<std::mutex> lock(m_);
flag_ = false;
}
cv_.notify_all();
}
void wait() const
{
std::unique_lock<std::mutex> lock(m_);
cv_.wait(lock, [this] { return flag_; });
}
template <typename Rep, typename Period>
bool wait_for(const std::chrono::duration<Rep, Period>& rel_time) const
{
std::unique_lock<std::mutex> lock(m_);
return cv_.wait_for(lock, rel_time, [this] { return flag_; });
}
template <typename Rep, typename Period>
bool wait_until(const std::chrono::duration<Rep, Period>& rel_time) const
{
std::unique_lock<std::mutex> lock(m_);
return cv_.wait_until(lock, rel_time, [this] { return flag_; });
}
};