2. 并发解决架构图
文章目录
- 一. 原子性操作实现
- 1.1 CPU支持的原子性操作
- 1.2 CPU原子性实现总结图
- 二. 并发架构解决图解
一. 原子性操作实现
1.1 CPU支持的原子性操作
我们以intel CPU举例,因为不同厂商对于CPU的原子性指令,都有各自的独特支持。因为我们在线上使用linux居多,并且是intel芯片。
这里就需涉及看intel开发手册,来了解intel提供了哪些原子性机制。但看之前我们可以猜测下,都会几种分类的原子性操作?CPU操作段描述符,脏页写回等,这属于CPU内部的操作,所以这种操作属于CPU自己的实现,而非我们关系,这种统称为自动原子性操作。还有一种是CPU提供给上层软件来操作保证的原子性指令,用于上层应用的复杂指令间的原子性保证。下面进行验证。
我们看的是intel 开发手册vol 3。
这里讲解锁原子性操作,也就是intel自己实现的指令原语
- 保证原子性操作
- 总线锁,使用lock前缀
- 缓存一致性协议
并还阐明若数据不在CPU缓存里,锁会退化成总线锁。
多处理器支持以下特征
- 保证系统内存一致性
- 保证缓存一致性
- 可预测指令写的顺序性
- 在一组处理器之间分配中断处理
- 通过利用当代操作系统和应用程序的多线程和多进程特性来提高系统性能。
而这里最重要一点保证了指令写的顺序性,也就是自己的原子性操作,解决了指令重拍问题
intel CPU自己实现了保证单字节,16bit/32bit的原子性
CPU自己还实现了,xchg指令的原子性,但我们使用时,无需考虑多核CPU带来的并发问题。
切换进程
段描述符加载
脏页
中断请求
lock指令的使用,是CPU提供给上层应用开发而产生
当使用lock需要搭配其他指令,来限制内存的独占性,但也要考虑内存的大小锁,导致的性能问题
1.2 CPU原子性实现总结图
这里笔者直接画了图,对上述的知识点做了总结
二. 并发架构解决图解
上面讨论了,并引申了很多术语上的东西,那么我们作为应用,如何合理利用并解决并发问题?
这里直接上图讲解,当多个线程执行同一个代码段时(代码段由多个指令构成),如何保证原子性?
这里就需要基于CPU指令的原子性来实现,CPU执行单指令时是保证原子性的,那么就通过CPU提供的指令,对一个标志位进行处理,若修改成功,代表抢到锁,可以执行代码段。若没抢到,则进入等待队列进行排队。但这里又引申出一个新的问题,若多个CPU同时执行失败,那么排队的并发问题如何解决?还是CPU的原子性指令。不过这时采用一个CAS自旋转方式,通过lock cmpxchg
方式来实现,进行合理的队列增加。当修改成功标志位的CPU执行完代码段时,就可以唤醒等待队列中的CPU,进行下一步处理。