c语言volatile原理,关于volatile的底层原理的一些补充

本文解析了一个Java程序,涉及两个线程协作:一个通过volatile变量`initFlag`实现同步,一个线程不断检查并反转flag,另一个线程修改flag引发同步。重点讲解了工作内存、主内存交互、volatile关键字的作用以及如何保证数据一致性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

描述下场景:一个main方法中有2个线程,initFlag是布尔类型的共享变量。一个线程是对initFlag做取反的死循环,一旦initFlag为true就跳出死循环,执行打印success的操作;另一个线程修改initFlag为true,触发第一个线程跳出死循环。第一个线程启动之后sleep下确保在启动第二个线程时第一个已经进入死循环。

13d13c81afe949d3169382e2616a278f.png

图中有一个主内存区,2个线程,每个线程有自己的工作内存,线程启动之后会从主内存中读取变量的副本存在工作内存中,通过read指令读取、load指令载入工作内存。第二个线程会对initFlag取反操作,通过use指令读取工作内存的变量,通过assign指令进行计算,把计算的新值赋值给工作内存的变量赋值。若是共享变量是volatile声明的,就会把新值立即回写到主内存,通过store指令读取工作内存的变量传入到主内存,然后在主内存中通过write指令给变量赋值。

回写时底层通过lock前缀指令执行锁定这块内存区域的缓存(缓存行锁定),然后执行store指令,这里需要注意的是所有的读写请求都通过总线,由总线传递给所有的CPU。其他CPU通过总线嗅探和缓存一致性协议来保证数据的一致性。具体是由每个CPU通过总线嗅探机制会监听自己工作内存中存在的变量,一旦发生回写,缓存一致性协议会使得其他CPU里缓存了改内存地址的数据无效,当其他CPU需要回写或者使用时会重新从内存中读取。在回写到主内存完成之后会执行unlock指令,提供给其他CPU使用。简单的说就是所有的读写请求都通过总线传递给所有的CPU,然后CPU去“嗅探”这些请求,当感知到数据变化时将自己的缓存的数据置为失效。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值