计算机在执行程序时,每条指令都是在CPU中执行的,而执行指令过程当中会涉及到数据的读取和写入。因为程序运行过程当中的临时数据是存放在主存(物理内存)当中的,这时就存在一个问题,因为CPU执行速度很快,而从内存读取数据和向内存写入数据的过程跟CPU执行指令的速度比起来要慢的多,所以若是任什么时候候对数据的操做都要经过和内存的交互来进行,会大大下降指令执行的速度。缓存
所以在CPU里面就有了高速缓存(Cache)的概念。当程序在运行过程当中,会将运算须要的数据从主存复制一份到CPU的高速缓存当中,那么CPU进行计算时就能够直接从它的高速缓存读取数据和向其中写入数据,当运算结束以后,再将高速缓存中的数据刷新到主存当中。这一过程在单线程运行是没有问题的,可是在多线程中运行就会有问题了。在多核CPU中,每条线程可能运行于不一样的CPU中,所以每一个线程运行时有本身的高速缓存(对单核CPU来讲,其实也会出现这种问题,只不过是以线程调度的形式来分别执行的)。这时CPU缓存中的值可能和缓存中的值不同,这就是著名的缓存一致性问题 。多线程
1. 经过在总线加LOCK#锁的方式
在早期的CPU当中,是经过在总线上加LOCK#锁的形式来解决缓存不一致的问题。由于CPU和其余部件进行通讯都是经过总线来进行的,若是对总线加LOCK#锁的话,也就是说阻塞了其余CPU对其余部件访问(如内存),从而使得只能有一个CPU能使用这个变量的内存。在总线上发出了LCOK#锁的信号,那么只有等待这段代码彻底执行完毕以后,其余CPU才能从其内存读取变量,而后进行相应的操做。这样就解决了缓存不一致的问题线程
2. 经过缓存一致性协议MESIblog
缓存一致性协议:内存
最出名的就是Intel 的MESI协议,MESI协议保证了每一个缓存中使用的共享变量的副本是一致的。它核心的思想是:当CPU写数据时,若是发现操做的变量是共享变量,即在其余CPU中也存在该变量的副本,会发出信号通知其余CPU将该变量的缓存行置为无效状态,所以当其余CPU须要读取这个变量时,发现本身缓存中缓存该变量的缓存行是无效的,那么它就会从内存从新读取。变量