memset操作是否具备线程间happens-before?非原子缓存读取一致性问询
C++原子操作与内存可见性问题解答
场景代码
全局变量定义:
std::atomic<int> x; char cache[1024];
线程1执行逻辑:
memset(cache, 0, 1024); x.store(20, std::memory_order::release);
线程2执行逻辑:
int z = x.load(std::memory_order::acquire); char c = cache[20];
问题解答
- memset操作是否具备“线程间happens-before”关系?
当线程2的x.load(acquire)成功读取到线程1通过x.store(release)写入的20时,memset操作和线程2中cache[20]的读取之间存在线程间的happens-before关系:
- 同一线程内,
memset必然happens-beforex.store(release)(线程内执行顺序的一致性规则); - 基于release-acquire同步规则,线程1的
x.store(release)同步于线程2的x.load(acquire); - 结合传递性,
memset就线程间happens-before线程2对cache[20]的读取。
如果线程2的x.load(acquire)没读到线程1写入的值(比如线程2先执行了load),这种线程间的happens-before关系就不成立。
- cache本身并非原子变量,能否确保线程2读取cache时获得线程1写入的值?
当线程2的x.load(acquire)读取到线程1写入的20时,可以确保。
release-acquire语义的核心作用就是建立跨线程的内存可见性:线程1中所有在release存储之前的内存写入操作(包括memset对整个cache的初始化),都会对线程2中acquire加载之后的内存读取操作可见。哪怕cache不是原子变量,这种同步关系已经保证了线程2读取cache[20]时,能拿到线程1写入的0值。
内容的提问来源于stack exchange,提问作者pippo
相关产品推荐
相关产品推荐

