[同步机制]-linux内核同步方法

1、原子操作

2、自旋锁、读写自旋锁

(自旋锁)
spin_lock() 获取指定的自旋锁
spin_lock_irq() 禁止本地中断并获取指定的锁
spin_lock_irqsave() 保存本地中断的当前状态,禁止本地中断,并获取指定的锁
spin_unlock() 释放指定的锁
spin_unlock_irq() 释放指定的锁,并激活本地中断
spin_unlock_irqstore() 释放指定的锁,并让本地中断恢复到以前状态

(读自旋锁)
read_lock() 获取指定的读锁
read_lock_irq() 禁止本地中断并获得指定读锁
read_lock_irqsave() 存储本地中断的当前状态,禁止本地中断并获得指定读锁
read_unlock() 释放指定的读锁
read_unlock_irq() 释放指定的读锁并激活本地中断
read_unlock_irqrestore() 释放指定的读锁并将本地中断恢复到指定前的状态

(写自旋锁)
write_lock() 获得指定的写锁
write_lock_irq() 禁止本地中断并获得指定写锁
write_lock_irqsave() 存储本地中断的当前状态,禁止本地中断并获得指定写锁
write_unlock() 释放指定的写锁
write_unlock_irq() 释放指定的写锁并激活本地中断
write_unlock_irqrestore() 释放指定的写锁并将本地中断恢复到指定前的状态

3、信号量、读写信号量、互斥体

(信号量)
down_interruptible(struct semaphore *) 以试图获得指定的信号量,如果信号量已被争用,则进入可中断睡眠状态
down(struct semaphore *) 以试图获得指定的信号量,如果信号量已被争用,则进入不可中断睡眠状态
up(struct semaphore *) 以释放指定的信号量,如果睡眠队列不空,则唤醒其中一个任务

(读写信号量)
读写信号量和信号量之间的关系 与 读写自旋锁和普通自旋锁之间的关系 差不多。
读写信号量都是二值信号量,即计数值最大为1,增加读者时,计数器不变,增加写者,计数器才减一。
也就是说读写信号量保护的临界区,最多只有一个写者,但可以有多个读者。
读写信号量的相关内容参见:<asm/rwsem.h> 具体实现与硬件体系结构有关

(互斥体)
mutex_lock(struct mutex *)
mutex_unlock(struct mutex *)

4、完成量

wait_for_completion(struct completion *)
complete(struct completion *)

5、大内核锁

大内核锁已经不再使用,只存在与一些遗留的代码中.
???

6、顺序锁

7、禁止抢占

preempt_disable() 增加抢占计数值,从而禁止内核抢占
preempt_enable() 减少抢占计算,并当该值降为0时检查和执行被挂起的需调度的任务

扫描二维码关注公众号,回复: 11439154 查看本文章

8、顺序和屏障

rmb() 阻止跨越屏障的载入动作发生重排序
read_barrier_depends() 阻止跨越屏障的具有数据依赖关系的载入动作重排序
wmb() 阻止跨越屏障的存储动作发生重排序
mb() 阻止跨越屏障的载入和存储动作重新排序
smp_rmb() 在SMP上提供rmb()功能,在UP上提供barrier()功能
smp_read_barrier_depends() 在SMP上提供read_barrier_depends()功能,在UP上提供barrier()功能
smp_wmb() 在SMP上提供wmb()功能,在UP上提供barrier()功能
smp_mb() 在SMP上提供mb()功能,在UP上提供barrier()功能
barrier() 阻止编译器跨越屏障对载入或存储操作进行优化

猜你喜欢

转载自blog.csdn.net/weixin_42135087/article/details/107485838