弱内存模型下RMW操作返回值正确性及线程互斥性问询
弱内存模型下RMW操作的返回值与原子性保证
结论
是的,恰好有且仅有一个线程会将对应的tX_is_last设为true,即t0_is_last ^ t1_is_last必然成立。
核心原因
不管是强内存模型还是弱内存模型(如ARM),C++标准对原子读-修改-写(RMW)操作的语义有严格保证:
- 任何原子RMW操作(比如
fetch_or)都是不可分割的原子序列:从读取原子变量的值,到基于该值计算新值,再写入新值,整个过程不会被其他线程的任何原子操作打断。 - RMW操作返回的值,一定是该操作开始执行时原子变量的当前值——这个值是操作写入前的“旧值”,不会出现读取到中间状态或不符合实际旧值的情况。
针对示例代码的具体分析
示例中shared初始值为0,两个线程分别执行fetch_or(1<<0)和fetch_or(1<<1),只有两种可能的执行结果:
- t0先完成RMW:
- t0读取到
shared=0,写入1(仅bit0置位),result0=0,不会触发t0_is_last的赋值。 - t1随后执行RMW,读取到
shared=1,写入3(bit0和bit1都置位),result1=1(即1<<0),因此t1_is_last被设为true。
- t0读取到
- t1先完成RMW:
- t1读取到
shared=0,写入2(仅bit1置位),result1=0,不会触发t1_is_last的赋值。 - t0随后执行RMW,读取到
shared=2,写入3,result0=2(即1<<1),因此t0_is_last被设为true。
- t1读取到
即使在弱内存模型CPU上,硬件会通过缓存一致性协议(如ARM的独占访问机制)保证两个RMW操作不会同时“看到”初始的0——必然有一个线程的RMW先完成,另一个线程的RMW只能看到前者写入后的结果,因此不可能出现两个线程都读取到0的情况,自然也不会出现t0_is_last和t1_is_last同时为true或同时为false的情况。
补充说明
弱内存模型的“松弛”特性,只会影响不同原子操作之间的可见性顺序(比如非RMW操作的重排),但不会破坏单个RMW操作的原子性和返回值的正确性——这是C++标准和硬件都必须保证的核心语义。
内容的提问来源于stack exchange,提问作者blonded04
相关产品推荐
相关产品推荐

