300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > 两个例子详解并发编程的可见性问题和有序性问题 通过volatile保证可见性和有序性以及

两个例子详解并发编程的可见性问题和有序性问题 通过volatile保证可见性和有序性以及

时间:2021-12-15 08:29:32

相关推荐

两个例子详解并发编程的可见性问题和有序性问题 通过volatile保证可见性和有序性以及

1. 并发编程的可见性问题

2. 并发编程的有序性问题

3. 使用volatile关键字解决可见性问题

4. 可见性问题的本质——缓存不一致

因为cpu执行速度很快,但是内存执行速度相对于CPU很慢,那么每次从内存取数据就拖慢了CPU的执行效率。实际上,在CPU和内存中有一层缓存,程序执行时在缓存操作数据,那么另一个缓存修改的数据是不会更新到当前程序缓存中的,也就出现了缓存不一致问题,也就出现了可见性问题。简易内存模型图如下。

5. 有序性问题的本质——指令重排

因为CPU或者编译器为了优化程序指令,会对没有依赖关系的程序指令进行重排。对于单线程来说,指令没有依赖关系,重排没有问题,但如果是并发编程,那么指令重排是有影响的。

6. volatile是怎么解决可见性、有序性问题的呢?也就是怎么解决缓存不一致和禁止指令重排的呢?

6.1 缓存不一致问题:存在该问题是某个线程只修改自己缓存的数据,没有将数据刷新到内存中,或者另一个线程只从自己的缓存读取数据,没有从内存中取数据,造成了数据“不可见”。如果有一种协议,当某个线程修改缓存数据后,数据会被刷新到内存中,同时让其他线程的缓存数据失效,重新从内存读取,那么就解决缓存不一致问题了。这个协议就是MESI缓存一致性协议,MESI表示缓存数据(通过缓存行存储,64个字节)的四种状态字母缩写,四种状态如下,当触发了MESI协议,就能保证数据一致,也就是保证了数据的可见性。volatile就是通过触发MESI协议来保证数据可见的。

① Modified:数据只在当前线程的缓存中,且缓存数据与内存数据不一致。

② Exclusive:数据只在当前线程的缓存中,且缓存与内存数据一致。

③ Shared:数据存在于多个线程的缓存中,且缓存数据与内存一致。

④ Invalid:数据无效。

6.2 禁止指令重排:对于指令重排序,我们设置某些规则,当CPU或编译器检测到指令存在这些规则,那么不进行指令重排,即可解决有序性问题。内存屏障对于volatile数据的读或者写操作时,会加入对应内存屏障来保证指令的有序性。具体有哪些内存屏障,以及内存屏障为什么是那样的设置,这里就不多叙述了,volatile写之前有StoreStore屏障,之后有StoreLoad屏障(万能屏障,兼具其它三种屏障功能);volatile读之后有LoadStore和LoadLoad屏障

两个例子详解并发编程的可见性问题和有序性问题 通过volatile保证可见性和有序性以及volatile的底层原理——缓存一致性协议MESI和内存屏障禁止指令重排

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。