【并发编程专题(一)】

  1. 冯诺依曼计算机模型
  2. 问题的出现
  3. 新问题的出现
  4. 总线加锁与MESI协议
  5. 线程是什么

1.冯诺依曼计算机模型

冯诺依曼计算机模型
输入单元包括键盘、鼠标、扫描仪、写字板等。输出单元包括显示器、打印机等。中央处理器(CPU):含有运算器和控制器等。存储器就是内存。我们这里主要关注CPU和内存的交互。
在这里插入图片描述
举个例子,当你在QQ上给别人发信息的时候,通过输入设备(鼠标键盘)把信号写到内存里去,CPU 从内存中取出数据并进行处理,运算完毕后再写回内存,内存将 CPU 处理过的数据交给输出设备,由输出设备进行数据的输出。对方电脑也是一样的过程。

2.问题的出现

在这里插入图片描述
打开你的任务管理器去看看CPU频率的单位——GHz,而内存频率是多少呢?大概就是1000MHz。当然高速度写的内存不是没有,就是贵。从性能价格比的角度出发,英特尔等处理器设计生产公司想到一个办法,就是用少量的高速缓存和大量的低速内存结合使用,共同为处理器提供数据。
现在,当中央处理器存取主内存某一单元时,计算机硬件就自动地将包括该单元在内的那一组单元内容调入高速缓存,于是,中央处理器就可以直接对高速缓存存储器进行存取。在整个处理过程中,如果中央处理器绝大多数存取主内存的操作能为存取高速缓存存储器所代替,计算机系统处理速度就能显著提高。
这相当于如果你在军训,你没有水壶(高速缓存),每次要喝水都要跑大半个操场去学院的水箱(主存)那里喝水,但如果你有水壶,装一次水(把数据读进自己高速缓存里),以后想喝水拿起水壶就喝到水了,速度是不是快很多呢?
所以,我们的计算机进化成这样,有了存储单元:
在这里插入图片描述在这里插入图片描述
上面这段文字可以读一读,知道存储单元有片内缓存和寄存器两个东西就行了。

3.新问题的出现

基于高速缓存的存储交互很好地解决了处理器与内存的速度矛盾,但是也引入了新的问题:缓存一致性(CacheCoherence)。当多个处理器的运算任务都涉及同一块主内存区域时,将可能导致各自的缓存数据不一致的情况,如果真的发生这种情况,那同步回到主内存时以谁的缓存数据为准呢?
在这里插入图片描述
比方说主存中有一个变量X=1,两个线程都要对这个数进行某种计算。各自读回去计算完,这个过程互相不知情,这个缓存是这个值,那个缓存是那个值,这怎么行?所以我们需要一种互相知会的机制,尽管有缓存,也使这一个变量值在每个缓存中是一样的值。这叫缓存一致。

4.总线加锁与MESI协议

在这里插入图片描述
总线(也叫CPU总线),你就把它看作所有部件通信的通道。各CPU和内存交互是要通过这些总线的。
在这里插入图片描述
举例:现在主存中有一个变量X=1,两个线程都要对这个数加1。在CPU1要做加操作的时候,其在总线上发出一个LOCK#信号,也就阻塞了其他CPU和内存的交流,使该处理器可以独享此共享内存。总线锁定非常霸道,把CPU和内存的通信给锁住了,使得在锁定期间,其他处理器不能操作其他内存地址的数据,从而开销较大,所以后来的CPU都提供了缓存一致性机制。

缓存一致性:缓存一致性机制就整体来说,是当某块CPU对缓存中的数据进行操作了之后,就通知其他CPU放弃储存在它们内部的缓存,或者从主内存中重新读取。

MESI 协议是以缓存行(缓存的基本数据单位,在Intel的CPU上一般是64字节)的几个状态来命名的(全名是Modified、Exclusive、 Share or Invalid)。该协议要求在每个缓存行上维护两个状态位,使得每个数据单位可能处于M、E、S和I这四种状态之一,各种状态含义如下:
M:被修改的。处于这一状态的数据,只在本CPU中有缓存数据,而其他CPU中没有。同时其状态相对于内存中的值来说,是已经被修改的,且没有更新到内存中。
E:独占的。处于这一状态的数据,只有在本CPU中有缓存,且其数据没有修改,即与内存中一致。
S:共享的。处于这一状态的数据在多个CPU中都有缓存,且与内存一致。
I:无效的。本CPU中的这份缓存已经无效。

举例:还是那个两个线程都想加1的例子。CPU1动作快一点,抢先读了值,且只有它有这个值,所以是独占状态。在这里插入图片描述
这时CPU2也读了值,CPU1是能监听到的,同时变成共享状态。
在这里插入图片描述
还是CPU1动作快一点,抢先修改了值,这时CPU2能知道这个值被某个人改了,于是使自己的这个变量无效,CPU1变为修改状态。在这里插入图片描述
注意一下,CPU2中缓存数据已经无效,如果它下一个动作想要读,那就只能从主存中读,这时MESI协议又规定了,一个处于M状态的缓存行,必须时刻监听所有试图读取该缓存行对应的主存地址的操作,如果监听到,则必须在此操作执行前把其缓存行中的数据写回CPU。说人话就是,CPU1原本是很悠闲的M状态,什么时候把值写回主存看心情,这时CPU1嗅探到CPU2想读,赶紧把值写回主存,免得人家又读到旧值。CPU2读回来后,两个又同时变共享状态。

在这里插入图片描述
提醒一下,不要认为缓存一致了就一定线程安全了。我上面一段话把“如果它下一个动作想要读”标成粗体就是想强调这个。如果CPU1动作非常快,在CPU2还没有读之前就已经加1了,状态从E变M,那么恭喜,缓存一致能让CPU2接着CPU1写回的2继续往上加,变成3,这一次没有出现线程安全问题。但是如果不幸,CPU1和CPU2同时把1读到自己缓存中了,CPU1加了1,变2,状态从S变M,CPU2里的缓存无效后,不会再重新从主存中读新值了,因为已经执行过读指令了,计算机是一根筋按指令顺序做事的,1读2加3写,一步一步来的,读完了该拿这个数加1,但是这个数是失效的不能用,那怎么办呢?没办法,CPU2它会算了。最后结果就是两个线程都加1,最后只加了一次,依然没有保证线程安全。

5.线程是什么

请看这篇

多CPU,多核,多进程,多线程以及进程和线程的简单理解以及区别

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值