> 技术文档 > std::atomic_thread_fence解释翻译

std::atomic_thread_fence解释翻译


cppreference.com

 

  • Page  页
  • Discussion  讨论

std:: atomic_thread_fence   C++   Concurrency support library并发支持库  

Defined in header 
在标题  中定义
extern \"C\" void atomic_thread_fence( std::memory_order order ) noexcept;
外部 “C” void atomic_thread_fence  std:: memory_order order  noexcept 
(since C++11)  (自 C++11 起)

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 by X (or the value would be written by release sequence headed by X if X were a release operation),
    Y 读取 X 写入的值(或者,如果 X 是释放操作,则该值将由以 X 为首的释放序列写入),
  • F is sequenced-before X in thread A.
    在线程 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 by X (or by the release sequence headed by X),
    Y 读取由 X 写入的值(或由以 X 为首的释放序列写入的值 ),
  • Y is sequenced-before F in thread B.
    在线程 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 modifies M in thread A,
    存在一个原子写入 X (具有任意内存顺序)来修改线程 A 中的 M ,
  • FA is sequenced-before X in thread A,
    FA 在线程 A 中先于 X 排序,
  • there exists an atomic read Y (with any memory order) in thread B,
    线程 B 中存在原子读取 Y (具有任意内存顺序),
  • Y reads the value written by X (or the value would be written by release sequence headed by X if X were a release operation),
    Y 读取 X 写入的值(或者,如果 X 是释放操作,则该值将由以 X 为首的释放序列写入),
  • Y is sequenced-before FB in thread B.
    在线程 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  参数

order   命令 - the memory ordering executed by this fence
该栅栏执行的内存排序

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  参见

memory_order  内存顺序 (C++11)  (C++11) defines memory ordering constraints for the given atomic operation
为给定的原子操作定义内存排序约束
(enum)  (枚举)
atomic_signal_fence  原子信号围栏 (C++11)  (C++11) fence between a thread and a signal handler executed in the same thread
线程和在同一线程中执行的信号处理程序之间的隔离
(function)  (功能)
C documentation for atomic_thread_fence
atomic_thread_fence 的 C 文档