std::atomic_thread_fence解释翻译
cppreference.com
- Page 页
- Discussion 讨论
std:: atomic_thread_fence C++ Concurrency support library并发支持库
在标题
中定义 外部 “C” void atomic_thread_fence ( std:: memory_order order ) noexcept ;
Establishes memory synchronization ordering of non-atomic and relaxed atomic accesses, as instructed by order, without an associated atomic operation. Note however, that at least one atomic operation is required to set up the synchronization, as described below.
按照 order 的指示,建立非原子访问和宽松原子访问的内存同步顺序 ,无需关联原子操作。但请注意,设置同步至少需要执行一个原子操作,如下所述。
Fence-atomic synchronization
栅栏原子同步
A release fence F
in thread A
synchronizes-with atomic acquire operation Y
in thread B
, if
线程 A
中的释放栅栏 F
与线程 B
中的原子获取操作 Y
同步,如果
- there exists an atomic store
X
(with any memory order),
存在一个原子存储X
(具有任意内存顺序), Y
reads the value written byX
(or the value would be written by release sequence headed by X ifX
were a release operation),
Y
读取X
写入的值(或者,如果X
是释放操作,则该值将由以 X 为首的释放序列写入),F
is sequenced-beforeX
in threadA
.
在线程A
中,F
在X
之前排序。
In this case, all non-atomic and relaxed atomic stores that are sequenced-before F
in thread A
will happen-before all non-atomic and relaxed atomic loads from the same locations made in thread B
after Y
.
在这种情况下,线程 A
中在 F
之前排序的所有非原子和宽松原子存储都将在 Y
之后在线程 B
中从相同位置进行的所有非原子和宽松原子加载之前发生 。
Atomic-fence synchronization
原子栅栏同步
An atomic release operation X
in thread A
synchronizes-with an acquire fence F
in thread B
, if
线程 A
中的原子释放操作 X
与线程 B
中的获取栅栏 F
同步,如果
- there exists an atomic read
Y
(with any memory order),
存在一个原子读取Y
(具有任意内存顺序), Y
reads the value written byX
(or by the release sequence headed by X),
Y
读取由X
写入的值(或由以 X 为首的释放序列写入的值 ),Y
is sequenced-beforeF
in threadB
.
在线程B
中,Y
在F
之前排序。
In this case, all non-atomic and relaxed atomic stores that are sequenced-before X
in thread A
will happen-before all non-atomic and relaxed atomic loads from the same locations made in thread B
after F
.
在这种情况下,线程 A
中在 X
之前排序的所有非原子和宽松原子存储都将在 F
之后在线程 B
中从相同位置进行的所有非原子和宽松原子加载之前发生 。
Fence-fence synchronization
栅栏-栅栏同步
A release fence FA
in thread A
synchronizes-with an acquire fence FB
in thread B
, if
线程 A
中的释放栅栏 FA
与线程 B
中的获取栅栏 FB
同步,如果
- there exists an atomic object
M
,
存在一个原子对象M
, - there exists an atomic write
X
(with any memory order) that modifiesM
in threadA
,
存在一个原子写入X
(具有任意内存顺序)来修改线程A
中的M
, FA
is sequenced-beforeX
in threadA
,
FA
在线程A
中先于X
排序,- there exists an atomic read
Y
(with any memory order) in threadB
,
线程B
中存在原子读取Y
(具有任意内存顺序), Y
reads the value written byX
(or the value would be written by release sequence headed by X ifX
were a release operation),
Y
读取X
写入的值(或者,如果X
是释放操作,则该值将由以 X 为首的释放序列写入),Y
is sequenced-beforeFB
in threadB
.
在线程B
中,Y
先于FB
排序。
In this case, all non-atomic and relaxed atomic stores that are sequenced-before FA
in thread A
will happen-before all non-atomic and relaxed atomic loads from the same locations made in thread B
after FB
.
在这种情况下,线程 A
中在 FA
之前排序的所有非原子和宽松原子存储都将发生在线程 B
中在 FB
之后从相同位置进行的所有非原子和宽松原子加载之前。
Depending on the value of the order parameter, the effects of this call are:
根据 order 参数的值,此调用的效果如下:
- When order == std::memory_order_relaxed, there are no effects.
当 order == std:: memory_order_relaxed 时,没有任何影响。 - When order == std::memory_order_acquire or order == std::memory_order_consume, is an acquire fence.
当 order == std:: memory_order_acquire 或 order == std:: memory_order_consume 时,是一个获取围栏。 - When order == std::memory_order_release, is a release fence.
当 order == std:: memory_order_release 时,是一个释放围栏。 - When order == std::memory_order_acq_rel, is both a release fence and an acquire fence.
当 order == std:: memory_order_acq_rel 时,既是释放围栏,又是获取围栏。 - When order == std::memory_order_seq_cst, is a sequentially-consistent ordering acquire fence and release fence.
当 order == std:: memory_order_seq_cst 时,是顺序一致的获取栅栏和释放栅栏。
Parameters 参数
该栅栏执行的内存排序
Notes 笔记
On x86 (including x86-64), atomic_thread_fence
functions issue no CPU instructions and only affect compile-time code motion, except for std::atomic_thread_fence(std::memory_order_seq_cst).
在 x86(包括 x86-64)上, atomic_thread_fence
函数不发出 CPU 指令并且仅影响编译时代码运动, std :: atomic_thread_fence ( std:: memory_order_seq_cst ) 除外。
atomic_thread_fence
imposes stronger synchronization constraints than an atomic store operation with the same std::memory_order. While an atomic store-release operation prevents all preceding reads and writes from moving past the store-release, an atomic_thread_fence
with std::memory_order_release ordering prevents all preceding reads and writes from moving past all subsequent stores.
与具有相同 std::memory_order 的原子存储操作相比, atomic_thread_fence
施加了更强的同步约束。原子存储-释放操作会阻止所有先前的读写操作超越存储-释放操作,而具有 std:: memory_order_release 顺序的 atomic_thread_fence
会阻止所有先前的读写操作超越所有后续的存储操作。
Fence-fence synchronization can be used to add synchronization to a sequence of several relaxed atomic operations, for example:
栅栏-栅栏同步可用于为多个宽松原子操作序列添加同步,例如:
// Globalstd::string computation(int);void print(std::string); std::atomic arr[3] = {-1, -1, -1};std::string data[1000]; //non-atomic data // Thread A, compute 3 values.void ThreadA(int v0, int v1, int v2){// assert(0 <= v0, v1, v2 < 1000); data[v0] = computation(v0); data[v1] = computation(v1); data[v2] = computation(v2); std::atomic_thread_fence(std::memory_order_release); std::atomic_store_explicit(&arr[0], v0, std::memory_order_relaxed); std::atomic_store_explicit(&arr[1], v1, std::memory_order_relaxed); std::atomic_store_explicit(&arr[2], v2, std::memory_order_relaxed);} // Thread B, prints between 0 and 3 values already computed.void ThreadB(){ int v0 = std::atomic_load_explicit(&arr[0], std::memory_order_relaxed); int v1 = std::atomic_load_explicit(&arr[1], std::memory_order_relaxed); int v2 = std::atomic_load_explicit(&arr[2], std::memory_order_relaxed); std::atomic_thread_fence(std::memory_order_acquire);// v0, v1, v2 might turn out to be -1, some or all of them.// Otherwise it is safe to read the non-atomic data because of the fences: if (v0 != -1) print(data[v0]); if (v1 != -1) print(data[v1]); if (v2 != -1) print(data[v2]);}
Example 例子
Scan an array of mailboxes, and process only the ones intended for us, without unnecessary synchronization. This example uses atomic-fence synchronization.
扫描邮箱数组,只处理发送给我们的邮箱,避免不必要的同步。本示例使用了原子栅栏同步。
const int num_mailboxes = 32;std::atomic mailbox_receiver[num_mailboxes];std::string mailbox_data[num_mailboxes]; // The writer threads update non-atomic shared data // and then update mailbox_receiver[i] as follows:mailbox_data[i] = ...;std::atomic_store_explicit(&mailbox_receiver[i], receiver_id, std::memory_order_release); // Reader thread needs to check all mailbox[i], but only needs to sync with one.for (int i = 0; i < num_mailboxes; ++i) if (std::atomic_load_explicit(&mailbox_receiver[i], std::memory_order_relaxed) == my_id) { // synchronize with just one writer std::atomic_thread_fence(std::memory_order_acquire); // guaranteed to observe everything done in the writer thread // before the atomic_store_explicit() do_work(mailbox_data[i]); }
See also 参见
为给定的原子操作定义内存排序约束
(enum) (枚举)
线程和在同一线程中执行的信号处理程序之间的隔离
(function) (功能)
atomic_thread_fence 的 C 文档