1. 临界区与竞争条件
临界区:多个线程可并发访问和操作的共享数据代码段
竞争条件:多个线程在同一临界区内同时执行
2. 竞争保护:加锁
避免竞争条件,让操作串行化。锁操作是原子的。
Linux中有不同种类的锁实现,区别在于获取不到锁时的行为表现。
3. 死锁
例子有:自死锁(非重入锁重入),ABBA死锁等。
预防死锁的一些规则:
- 按顺序加锁
- 防止饥饿
- 非重入锁避免重入
- 加锁方案尽量简单
死锁的必要条件:
- 锁互斥
- 请求锁时,获取方要保持锁
- 锁不可抢占
- 循环等待
Linux有检测死锁的工具。
4. 竞争和扩展性
当一个线程占用了锁,其它线程尝试获取时,产生竞争状态。高度竞争会导致性能瓶颈,扩展性降低。
而影响扩展性的还有锁的粒度:
- 粒度小,竞争不明显时,开销会过大(主要是空间)
- 粒度大,竞争明显时,扩展性明显降低