定义于头文件
<atomic>
|
||
extern "C" void atomic_thread_fence( std::memory_order order ) noexcept;
|
(C++11 起) | |
建立非原子和宽松原子访问的以 order
指示的内存同步顺序,而无关联的原子操作。
目录 |
线程 A 中的释放栅栏 F 同步于线程 B 中的原子获得操作 Y ,若
此情况下,所有线程 A 中先发生于 X 的非原子和宽松原子存储将同步于所有 F 后的,线程 B 中从同一位置的非原子和宽松原子加载。
线程 A 中的原子释放操作 X 同步于线程 B 中的获得栅栏 F ,若
此情况下,线程 A 中所有发生先于 X 的非原子和宽松原子存储,将同步于所有 F 后的,线程 B 中从同一位置的非原子和宽松原子加载。
线程 A 中的释放栅栏 FA 同步于线程 B 中的获得栅栏 FB ,若
此情况下,线程 A 中所有先发生于 FA 的非原子和宽松原子存储,将同步于所有 FB 后的,线程 B 中从同一位置的非原子和宽松原子加载。
order | - | 此栅栏所执行的内存顺序 |
(无)
atomic_thread_fence
强加的同步制约强于带同一 std::memory_order 的原子存储操作。在原子存储释放操作阻止所有前驱写入被移动到存储释放之后的同时,带 memory_order_release
顺序的 atomic_thread_fence
还阻止所有前驱写入被移动到后继存储之后。
栅栏栅栏同步能用于添加同步到数个宽松原子操作的序列,例如
// 全局 std::string computation(int); void print( std::string ); std::atomic<int> arr[3] = { -1, -1, -1 }; std::string data[1000] // 非原子数据 // 线程 A ,计算 3 个值 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); } // 线程 B ,打印已经计算的 0 与 3 之间的值。 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 可能全部或部分结果为 -1 。 // 其他情况下读取非原子数据是安全的,因为栅栏: if( v0 != -1 ) { print( data[v0] ); } if( v1 != -1 ) { print( data[v1] ); } if( v2 != -1 ) { print( data[v2] ); } }
扫描邮箱数组,并只处理我们打算处理的一个,而无不必要的同步。
此示例使用内存栅栏同步。
const int num_mailboxes = 32; std::atomic<int> mailbox_receiver[num_mailboxes]; std::string mailbox_data[num_mailboxes]; // 写者线程更新非原子共享数据 // 然后更新 mailbox_receiver[i] 如下 mailbox_data[i] = ...; std::atomic_store_explicit(&mailbox_receiver[i], receiver_id, std::memory_order_release); // 读者线程需要检查所有 mailbox[i] ,但只需与一个同步 for (int i = 0; i < num_mailboxes; ++i) { if (std::atomic_load_explicit(&mailbox_receiver[i], std::memory_order_relaxed) == my_id) { std::atomic_thread_fence(std::memory_order_acquire); // 恰与一个写者同步 do_work( mailbox_data[i] ); // 保证观测到 atomic_store_explicit() // 之前写者线程所做的任何事 } }
(C++11)
|
为给定的原子操作定义内存顺序制约 (typedef) |
(C++11)
|
线程与执行于同一线程的信号处理函数间的栅栏 (函数) |
atomic_thread_fence的 C 文档
|