std::atomic_thread_fence
STD::原子[医]螺纹[医]篱笆
Defined in header | | |
---|---|---|
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
排序可以防止所有前面的写操作移动到所有后续存储区。
篱笆同步可以用来将同步添加到几个轻松的原子操作序列中,例如。
二次
//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] }
}
二次
实例
扫描一个邮箱数组,并且只处理为我们准备的邮箱,没有不必要的同步。
此示例使用原子围栏同步。
二次
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原子文档[医]螺纹[医]篱笆
© cppreference.com
在CreativeCommonsAttribution下授权-ShareAlike未移植许可v3.0。