我有两个线程,并且被第二线程设置一个标志。 我可以用一个atomic_bool
,但我希望能够等待*的标志被第一个线程上设置。 我怎样才能做到这一点?
我不能使用condition_variable
我猜的,因为如果第二个线程调用notify_one
第一个线程等待开始前,该线程将没有醒来。
此外,检查是否标志已经设置应该是相当快的。 我想这应该是很简单的,但我只是卡住了,所以我问在这里。 提前致谢。
*编辑:当然座不旺等待。 很抱歉,如果说不清楚。
我有两个线程,并且被第二线程设置一个标志。 我可以用一个atomic_bool
,但我希望能够等待*的标志被第一个线程上设置。 我怎样才能做到这一点?
我不能使用condition_variable
我猜的,因为如果第二个线程调用notify_one
第一个线程等待开始前,该线程将没有醒来。
此外,检查是否标志已经设置应该是相当快的。 我想这应该是很简单的,但我只是卡住了,所以我问在这里。 提前致谢。
*编辑:当然座不旺等待。 很抱歉,如果说不清楚。
随着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_; });
}
};
bool go = false;
std::mutex mtx;
std::condition_variable cnd;
// waiting thread:
std::unique_lock<std::mutex> lck(mtx);
while (!go)
cnd.wait(lock);
// when we get here we know that go is true, and we have the lock
// signalling thread:
{
std::unique_lock<std::mutex> lck(mtx);
go = true;
cnd.notify_one();
}
// now we've released the lock, so the waiting thread will make progress
到底是什么平台? 在我们使用POSIX兼容的平台
sem_t semaphore;
sem_init( &semaphore , 0 , x );
得到与x的初始值的信号。 然后用
sem_wait(&semaphore ); sem_post(&semaphore);
你可以同步两个线程。 记住申报semaphore
作为一个全局变量来确保两个线程可以访问它(或通过实现相同的任何其他方式)。
所以长话短说,您可以:
sem_t semaphore;
sem_init(&semaphore, 0 , 0 );
void thread2(){
sem_post(&semaphore); //second thread --A
}
void thread1(){
sem_wait(&semaphore); // wait until thread2() executes line A
}
应该有类似的实用程序,以实现在Win32一样了。