19

C++11 有 std::condition_variable,它的等待函数是

template< class Predicate >
void wait( std::unique_lock<std::mutex>& lock, Predicate pred );

它需要一个互斥锁。

据我了解 - 它的 notify_one 可以在不同步的情况下调用(我知道惯用的方法是将它与互斥锁一起使用)。

我有一个已经在内部同步的对象- 所以我不需要互斥锁来保护它。一个线程应该等待与该对象关联的某个事件,而其他线程将被通知。

如何在 C++11 中没有互斥锁的情况下进行此类通知?也就是说,使用condition_variable 很容易,但它需要一个互斥体。我考虑过使用假互斥类型,但 std::mutex 被钉在等待界面中。

一种选择是轮询 std::atomic_flag + sleep,但我不喜欢睡觉。

4

3 回答 3

14

使用std::condition_variable_any您可以使用任何实现BasicLockable概念的类。

对此我有一种不好的感觉,我检查了std::condition_variable_anylibc++ 的实现。事实证明,它使用 a plainstd::condition_variable和 a std::shared_ptrto a std::mutex,因此肯定会涉及一些开销,而无需深入挖掘。(这里有一些关于 SO 的其他帖子涵盖了这一点,尽管我首先必须搜索它)
因此,我可能会建议重新设计您的案例,以便同步实际上只能由保护普通条件变量的互斥锁完成。

于 2013-04-08T14:59:46.647 回答
6

在某些线程模型中(尽管我怀疑现代模型),需要互斥锁来保护条件变量本身(而不是您正在同步的对象)免受并发访问。如果条件变量不受互斥锁保护,您可能会遇到条件本身的问题。

请参阅为什么 pthread 的条件变量函数需要互斥锁?

于 2013-04-08T15:10:48.623 回答
1

我有一些对象,它已经在内部同步了——我不需要互斥锁来保护它。一个线程应该等待与该对象关联的某个事件,而其他线程会通知。

如果您不持有互斥锁,则等待线程将错过通知,无论您是使用condition_variable还是condition_variable_any使用内部互斥锁。

您需要将至少一位额外信息与条件变量相关联,并且该位应受互斥体保护。

于 2013-04-08T15:17:06.063 回答