使用原子和 condition_variables 进行虚假唤醒

Spurious wakeup with atomics and condition_variables

std::atomic<T>std::condition_variable 都有成员 waitnotify_one 函数。在某些应用程序中,程序员可以选择使用其中一种来实现同步目的。这些 wait 函数的一个目标是它们应该与操作系统协调以最大限度地减少虚假唤醒。也就是说,操作系统应避免唤醒 wait-ing 线程,直到 notify_onenotify_all 被调用。

在我的机器上,sizeof(std::atomic<T>)sizeof(T)sizeof(std::condition_variable)是72。如果排除std::atomic<T>T成员,那么std::condition_variable 保留 72 个字节用于同步目的,而 sizeof(std::atomic<T>) 保留 0 个字节。

我的问题:我应该期待 std::condition_variablestd::atomic<T>wait 函数之间的不同行为吗?例如,std::condition_variable 应该减少虚假唤醒吗?

std::atomic<T>::wait()

std::atomic<T>::notify_one()

std::condition_variable::wait()

std::condition_variable::notify_one()

My question: should I expect different behavior between std::condition_variable's and std::atomic<T>'s wait functions? For example, should std::condition_variable have fewer spurious wakeups?

std::atomic::wait 没有虚假唤醒。该标准保证观察到更改的值,它在 [atomics.types.generic.general]/30:

中表示

Effects: Repeatedly performs the following steps, in order:

(30.1) Evaluates load(order) and compares its value representation for equality against that of old.

(30.2) If they compare unequal, returns.

(30.3) Blocks until it is unblocked by an atomic notifying operation or is unblocked spuriously.

因此,如果原子等待的底层实现进行虚假唤醒,它们会被 C++ 标准库实现隐藏

如果您的问题是关于 原子或条件变量的底层实现中是否有更多或更少的虚假唤醒,那么它是特定于实现的。将取决于操作系统和库实现。最有可能的答案是:不,因为最终实现,其中 OS 进行内核调用很可能是相同的。