PVR*_*VRT 12 c++ condition-variable stdatomic c++20
我正在浏览“原子操作库”,并遇到了原子“等待”和“notify_ ”方法的新 C++20 功能。我很好奇 std::condition_variable 的 'wait' 和 'notify_ ' 方法有何不同。
整个使用模式有所不同。
condition_variable
等待需要互斥锁。在通知之前应该使用相同的互斥锁:
std::mutex mtx;
std::condition_variable cv;
bool condition();
void change_condition();
...
std::unique_lock<std::mutex> lock(mtx);
while (!condition())
{
cv.wait(lock);
}
...
std::unique_lock<std::mutex> lock(mtx);
change_condition();
lock.unlock();
cv.notify_one();
Run Code Online (Sandbox Code Playgroud)
现在,如果您有带有条件变量的原子,您仍然需要锁定:
std::mutex mtx;
std::condition_variable cv;
std::atomic<bool> condition;
...
std::unique_lock<std::mutex> lock(mtx);
while (!condition.load())
{
cv.wait(lock);
}
...
std::unique_lock<std::mutex> lock(mtx);
condition.store(true);
lock.unlock();
cv.notify_one();
Run Code Online (Sandbox Code Playgroud)
Atomic 本身不需要加锁保护,因此可以在不加锁的情况下进行修改。但是,仍然需要互斥锁来与等待同步并避免丢失唤醒。唤醒线程的替代方法如下:
condition.store(true);
std::unique_lock<std::mutex> lock(mtx);
lock.unlock();
cv.notify_one();
Run Code Online (Sandbox Code Playgroud)
互斥锁不能省略,即使在通知端也是如此。
(并且您无法摆脱condiion_variable_any
在其lock
/中不执行任何操作的“空互斥锁” unlock
)。
现在,原子等待。除了在另一个答案中提到的没有虚假唤醒之外,不需要互斥锁:
std::atomic<bool> condition;
...
condition.wait(false);
...
condition.store(true);
condition.notify_one();
Run Code Online (Sandbox Code Playgroud)
STD:原子wait
,notify_all
并且notify_one
方法类似于条件变量的方法。它们允许通过使用更高效和轻量级的原子变量来实现以前需要条件变量的逻辑。
该wait
函数阻塞线程,直到原子对象的值被修改。它需要一个参数来与原子对象的值进行比较。它反复执行:
notify_one
或通知notify_all
,或者线程被虚假地解除阻塞。注意:wait
保证仅在值已更改时返回,即使底层实现虚假地解除阻塞。
您可以在此处找到实现:https : //github.com/ogiroux/atomic_wait/。
策略是这样选择的,按平台: