
一、内核同步基本概念
1.1 临界区与竞态条件
- 临界区:访问共享资源的代码段
- 竞态条件:多个执行路径同时进入临界区导致的不确定性行为
1.2 同步问题的来源
- 对称多处理(SMP)系统
- 内核抢占
- 中断处理
- 延迟操作(如软中断)
二、Linux内核同步机制
2.1 原子操作
atomic_t v = ATOMIC_INIT(0);
atomic_inc(&v);
2.2 自旋锁(spinlock)
DEFINE_SPINLOCK(my_lock);
spin_lock(&my_lock);
spin_unlock(&my_lock);
2.3 信号量(semaphore)
struct semaphore sem;
sema_init(&sem, 1);
down(&sem);
up(&sem);
2.4 互斥锁(mutex)
struct mutex my_mutex;
mutex_init(&my_mutex);
mutex_lock(&my_mutex);
mutex_unlock(&my_mutex);
三、同步机制选择原则
机制 | 适用场景 | 开销 | 注意事项 |
---|
原子操作 | 简单变量操作 | 最低 | 仅适用于整数类型 |
自旋锁 | 短期锁定,不可睡眠上下文 | 中等 | 可能造成CPU空转 |
信号量 | 可能阻塞的长临界区 | 较高 | 可能导致进程调度 |
互斥锁 | 用户上下文长临界区 | 较高 | 比信号量更高效 |
四、死锁预防
- 按固定顺序获取多个锁
- 避免在持有锁时请求新锁
- 使用
lockdep
工具检测潜在死锁
五、最新发展
- RCU(Read-Copy-Update):适用于读多写少场景
- 顺序锁(seqlock):适用于写操作频繁但快速的场景