关于C++中fetch_xx、compare_and_swap及exchange的内存序疑问
C++原子RMW操作的内存序细节
针对你提到的原子读-改-写(RWM)操作内存序问题,直接给出结论和细节:
fetch_xx系列操作
在代码int item_index=count.fetch_sub(1,std::memory_order_acquire);中,存储(store)部分的内存序并不是默认的memory_order_seq_cst。
当给fetch_sub这类RMW操作只传一个内存序参数时,这个参数会分别约束操作里的加载和存储行为,遵循以下规则:
- 若参数是
memory_order_acquire:加载部分遵循acquire语义,存储部分为memory_order_relaxed(无同步约束) - 若参数是
memory_order_release:加载部分为relaxed,存储部分遵循release语义 - 若参数是
memory_order_acq_rel:加载是acquire,存储是release - 若参数是
memory_order_seq_cst:整个操作的加载和存储都遵循seq_cst语义,且参与全局同步顺序 - 若参数是
memory_order_relaxed:加载和存储都无同步约束
compare_and_swap(CAS)操作
CAS操作(比如compare_exchange_weak/strong)的情况分两种:
- 只传成功内存序参数时:
- 操作成功时:遵循你指定的内存序(比如传acquire的话,加载是acquire,存储是relaxed;传acq_rel则加载acquire、存储release)
- 操作失败时:默认使用对应加载语义的内存序(比如成功参数是acquire,失败就是acquire;成功参数是release,失败就是relaxed;成功参数是seq_cst,失败也是seq_cst)
- 若需要分别指定成功和失败的内存序,可以传入两个参数(例如
compare_exchange_weak(&val, &old, success_order, failure_order))
exchange操作
exchange和fetch_xx属于同一类RMW操作,规则完全一致:只传一个内存序参数时,该参数按上述规则分别约束加载和存储部分,不会默认使用seq_cst作为存储序。
内容的提问来源于stack exchange,提问作者x f
相关产品推荐
相关产品推荐

