在前面JMM内存模型文章中,我有写到多个线程并发访问一个主内存的共享变量时,这些线程会在各自的工作内存中拷贝一份共享变量的副本,那么这就带来了一个问题,一个线程对共享变量进行修改后,其他的线程该如何感知到共享变量的改变从而做出适当的反应,确保后续线程读取这个共享变量的时候,总是最新的值,从而防止出现脏数据的情况。说到这,就不得不说一下缓存一致性的由来。
首先我这里放上一张CPU内核简易结构图
以上图为例,在多核CPU中,每个内核都有自己的缓存,这就引来的一个问题,当缓存的数据与内存中的数据发生不一致的话该怎么办?于是就引来了缓存一致性协议啦。
MESI协议中一个缓存条目的状态Flag值分为以下四种
如下图,就是MESI的概要图。
如下案例,在内存中存在一个count共享变量,现在 "线程0" 需要用到该变量,那么 "线程0" 会从内存中通过bus总线将变量副本拷贝到缓存中,需要注意的是,线程都会对bus总线进行监听,例如 "线程0" 读取了共享变量,因为 "线程1"对bus总线进行了监听,所以它是知道的 "线程0" 进行了读取操作。但是目前为止该缓存变量它的状态为 "E(独占)",为什么为独占?因为该变量只被一个线程所使用。
总线锁的概念:将总线锁住,只有一个内核线程能够操作该变量,其他的线程只能默默的看着它进行操作啦,它的坏处在于,由多核的CPU变成了单核CPU操作效率大幅度的降低。
不知道大家伙看到这,对CPU底层对多线程数据处理,以及它的安全性问题是否有一个比较清晰的认知了呢?关于CPU底层有很多涉及到硬件层面的内容啦,大家伙感兴趣可自行查阅相关文档哦~
我是黎明大大,我知道我没有惊世的才华,也没有超于凡人的能力,但毕竟我还有一个不屈服,敢于选择向命运冲锋的灵魂,和一个就是伤痕累累也要义无反顾走下去的心。
如果您觉得本文对您有帮助,还请关注点赞一波,后期将不间断更新更多技术文章