首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

std::atomic_thread_fence

Defined in header <atomic>

?

?

extern "C" void atomic_thread_fence( std::memory_order order );

?

(since C++11)

建立存储器同步排序非原子访问和轻松原子访问,按照order,没有关联的原子操作。

栅栏-原子同步

线程A中的释放栅栏F与原子同步获取操作Y在线程B中,如果。

  • 存在一个具有任意内存顺序%29的原子存储区X%28
  • Y读取由X%28写入的值,否则值将由以X为首的释放序列如果X是一个释放操作%29
  • F在线程A中在X之前被排序

在这种情况下,所有非原子原子和轻松原子存储发生-之前线程A中的X将是同步所有非原子和松弛的原子负载都来自在F之后的B线程中相同的位置。

原子栅栏同步

原子释放操作线程A中的X与线程B中的获取栅栏F同步,如果.

  • 存在一个具有任意内存顺序(%29)的原子读Y%28
  • Y读取由X%28或以X为首的释放序列%29
  • 在线程B中,在F之前对y进行了排序。

在这种情况下,所有非原子原子和轻松原子存储发生-之前线程A中的X将是同步所有非原子和松弛的原子负载都来自在F之后的B线程中相同的位置。

栅栏-栅栏同步

线程A中的释放栅栏FA与线程B中的获取栅栏FB同步,如果。

  • 存在一个原子物体M,
  • 存在一个原子写X%28,其内存顺序%29在线程A中修改M
  • 在线程A中,在X之前对FA进行了排序。
  • 线程B中存在一个具有任意内存顺序%29的原子读取Y%28
  • Y读取由X%28写入的值,否则值将由以X为首的释放序列如果X是一个释放操作%29
  • 在线程B中,在fb之前对y进行了排序。

在这种情况下,所有非原子原子和轻松原子存储发生-之前线程A中的FA将是同步所有非原子和放松的原子负载来自相同的位置,在线程B后FB.

参数

order

-

the memory ordering executed by this fence

返回值

%280%29

例外

noexcept规格:

noexcept

注记

atomic_thread_fence比具有相同的原子存储操作更强的同步约束。std::memory_order当原子存储释放操作阻止前面的所有写入通过存储释放时,atomic_thread_fence带着memory_order_release排序可以防止所有前面的写操作移动到所有后续存储区。

篱笆同步可以用来将同步添加到几个轻松的原子操作序列中,例如。

二次

代码语言:javascript
复制
//Global
std::string computation(int);
void print( std::string );
 
std::atomic<int> 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] ); }
}

二次

实例

扫描一个邮箱数组,并且只处理为我们准备的邮箱,没有不必要的同步。

此示例使用原子围栏同步。

二次

代码语言:javascript
复制
const int num_mailboxes = 32;
std::atomic<int> 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) {
        std::atomic_thread_fence(std::memory_order_acquire); // synchronize with just one writer
        do_work( mailbox_data[i] ); // guaranteed to observe everything done in the writer thread before
                    // the atomic_store_explicit()
    }
 }

二次

另见

memory_order (C++11)

defines memory ordering constraints for the given atomic operation (typedef)

atomic_signal_fence (C++11)

fence between a thread and a signal handler executed in the same thread (function)

C原子文档[医]螺纹[医]篱笆

代码语言:txt
复制
 ? cppreference.com

在CreativeCommonsAttribution下授权-ShareAlike未移植许可v3.0。

扫码关注腾讯云开发者

领取腾讯云代金券

http://www.vxiaotou.com