理解好并发处理,有几个小概念是相关的。
1.由于图灵机本身是依赖side-effect来工作,故同步互斥机制便有了必要性。代码角度来看,如果依赖了共享的变量,便意味着可能需要同步保护。如果是lamada演算的函数式编程,是不需要同步保护滴。
2.死锁dead-lock的必要4条件。1. 资源的独占性(不可分享) 2. 拥有者占有后不可剥夺(不可抢占) 3. 拥有者可占有多重资源
4.环路等待
序号 | 类型 | 分析 |
1 | spinlock自旋锁 | 就像在碗里抢一把钥匙,抢不到的一直看着碗等。 适合场景: 1.简短快速的保护段。 自旋锁安全safe: 1.拥有者不能在保护段调用任何会休眠的函数。 原因有2:a)休眠时间不会短,会造成其它SMP核无畏的开销 b)容易引发死锁,单核下,抢占关闭,不能调度直接死锁。多核下会好一点,当前核直接死锁,如果其它SMP核重入此保护段,会卡住此SMP(因此是先关抢占),运气不好耗尽所有的SMP时,系统hang住。 2.如果会在IRQ上下文用spinlock,一定要用IRQ版本。原因是不用IRQ版本,spinlock语义失效。spinlock能关闭抢占,却不能避免中断抢占执行。 |
2. | 读写自旋锁rwlock | 本质上是优化spinlock的性能。 原理上是死锁条件第一条入手:独占性。 多读其实可以共享,多写/读写是互斥的。 这样改善了并发读操作,其它不变。 带来的side-effect副作用:更容易导致写者饥饿,原因是读者能持续接力拿到key.而写者必然等无读者时才能拿到key.而不像spinlock大家的对等的机率抢到。 |
3. | 顺序锁seqlock | 本质上是优化spinlock的性能。 特点是对写者友好。 原理上是死锁条件第一,二条入手:独占性,不可抢占。 多读共享,读写是不再强互斥的。对于写者间还是独占性。 策略:如果在写,新来的读者等待写完。如果是写者不考虑读者存在,直接访问。读者是通过小技巧(比较保护断前后计数值变化情况)来确定读的过程中不存在写者。 实现依赖:依靠体系int型操作smb内存的原子性 顺序锁safe: 1.读者保护段并发分析,通常只适合数值型数据。 由于读写不保证互斥,也就是在保护段读的过程中,会被写者修改,因此读者此时是不能信任读到的数据。直到退出保护段才能保证之前在保护段的数据是可信的,由于这个时间差。通常只适合数值型数据,如果是复杂数据操作要仔细分析读写冲突下的风险,否则会遇到麻烦。 比如:保护段内访问指针型数据,存在风险。可能指针正在被写者改变。 |
4 | RCU锁 | |