第9章 内核同步介绍
临界区和竞争条件
临界区就是访问和操作共享数据的代码段。多个线程并发访问同一个资源通常是不安全的,必须保证这些操作是原子的。如果两个执行线程有可能处于一个临界区中同时执行,那么这就是一个bug,称它是竞争条件(race conditions)。因为竞争引起的错误非常不易重现,所以调试才会非常困难。避免并发和防止竞争条件称为同步(synchronization)。
造成并发执行的原因
用户空间,用户程序会被调度程序抢占和重新调度。
内核空间,类似原因:
- 中断
- 软中断和tasklet
- 内核抢占
- 睡眠及与用户空间的同步
- 对称多处理
什么数据需要加锁
- 全局?其它线程能否访问?
- 会不会在上下文中共享?会不会在两个不同的中断处理程序中共享?
- 可不可被抢占?调度的新程序会不会访问同一数据?
- 会不会阻塞在某些资源上,对共享数据的处理?
…
死锁
要有一个或多个执行线程和一个或多个资源,每个线程都在等待其中的一个资源,但是所有资源都被占用。但是线程不会释放已经占有的资源,死锁发生。
预防:
- 按顺序加锁
- 防止发生饥饿
- 不要重复请求同一个锁
- 设计力求简单
争用和扩展性
锁的争用(lock contention),锁被频繁持有或长时间持有,会降低系统的性能。
扩展性(scalability)是对系统可扩展性的一个度量。
加锁粒度用来描述加锁保护的数据规模。使用时处于过大和过小之间。
总结
保护数据不被并发访问!