Ale*_*iev 8 c++ memory-barriers language-lawyer stdatomic c++20
libc++在方法中std::counting_semaphore使用原子增量:memory_order_releaserelease
void release(ptrdiff_t __update = 1)
{
if(0 < __a.fetch_add(__update, memory_order_release))
;
else if(__update > 1)
__a.notify_all();
else
__a.notify_one();
}
Run Code Online (Sandbox Code Playgroud)
并memory_order_acquire在acquire方法中将交换与成功的内存顺序进行比较:
void acquire()
{
auto const __test_fn = [=]() -> bool {
auto __old = __a.load(memory_order_relaxed);
return (__old != 0) && __a.compare_exchange_strong(__old, __old - 1, memory_order_acquire, memory_order_relaxed);
};
__cxx_atomic_wait(&__a.__a_, __test_fn);
}
Run Code Online (Sandbox Code Playgroud)
使获取与发布同步的明显选择。
但是,C++20 草案说:
Run Code Online (Sandbox Code Playgroud)void release(ptrdiff_t update = 1);...
同步:强烈发生在调用 try_acquire 之前,观察效果的结果。
强发生在比同步之前有点多,C++20 草案说:
评估 A 强烈发生在评估 D 之前,如果,
- (12.1) A 在 D 之前被排序,或
- (12.2) A 与 D 同步,并且 A 和 D 都是顺序一致的原子操作([atomics.order]),或者
- (12.3) 存在评估 B 和 C,使得 A 在 B 之前被排序,B 只是发生在 C 之前,并且 C 在 D 之前被排序,或者
- (12.4) 存在一个评估 B,使得 A 在 B 之前强烈发生,而 B 在 D 之前强烈发生。
我想 12.2 最适合这里,其中 A 是fetch_add,D 是compare_exchange_strong。但是除了被同步之外,他们应该一直是seq_cst!
尝试 12.3 似乎也无济于事。我们称fetch_addB 和compare_exchange_strongC。很好,但是 A 和 D 在哪里?
那么它是如何工作的(根据 C++20 标准草案)?
这同样适用于std::latch和std::barrier。
我选择了一个 ( std::semaphore) 来轻松引用特定的段落和行。
| 归档时间: |
|
| 查看次数: |
441 次 |
| 最近记录: |