Linux驱动设计之信号量

1.信号量的定义

    信号量(semphore)是用于保护临界区的一种常用方法,它的使用方式和自旋锁类似。信号量的本质是一种数据操作锁,它本身不具有数据交换的功能,而是通过控制其他的通信资源(文件,外部设备)来实现进程间通信,它本身只是一种外部资源的标识。信号量在此过程中负责数据操作的互斥、同步等功能。

2.信号量的主要操作

  2.1、 定义信号量

下列代码定义名称为sem的信号量:
struct semaphore sem;

  2.2、 初始化信号量

可用void sema_init(struct semaphore *sem, int val);直接创建,其中val为信号量初值。

也可以用两个宏来定义和初始化信号量的值为1或0:

DECLARE_MUTEX(name) : 定义信号量name并初始化为1

DECLARE_MUTEX_LOCKED(name) : 定义信号量name并初始化为0

还可以用下面的函数初始化:

void init_MUTEX(struct semaphore *sem); //初始化信号量的值为1

void init_MUTEX_LOCKED(struct semaphore *sem); //初始化信号量的值为0


    2.3、信号量的原子操作

* void down(struct semaphore *sem); //用来获取信号量,如果信号量值大于或等于0,获取信号量,否则进入睡眠状态,睡眠状态不可唤醒

* void down_interruptible(struct semephore *sem); //用来获取信号量,如果信号量大于或等于0,获取信号量,否则进入睡眠状态,等待信号量被释放后,激活该程。

* void down_trylock(struct semaphore *sem); //试图获取信号量,如果信号量已被其他进程获取,则立刻返回非零值,调用者不会睡眠

* void up(struct semaphore *sem); //释放信号量,并唤醒等待该资源进程队列的第一个进程。

3 信号量与自旋锁的区别

(1)当锁不能获取到时,使用信号量的开销是进程上下文切换时间,使用自旋锁的开销是等待获取自旋锁;
(2)信号量所保护的临界区可能会引起阻塞,而自旋锁则绝对要避免用来保护包含这样的代码,因为阻塞意味着要进行进程的切换,如果进程被切换出去后,另一个进程企图要获取本自旋锁,死锁就会发生。
(3)信号量存在于进程的上下文,因此,如果保护的共享资源需要在中断或软中断情况下使用,则在信号量和自旋锁之间只能选择自旋锁。当然如果一定要使用信号量,则只能通过down_trylock方式进行,不能获取就立即返回避免阻塞。

你可能感兴趣的:(LINUX驱动研究)