信号量

信号量

信号量的引入

对于操作共享空间时间较长的场景,对于自旋锁的使用不太合适,自旋锁适用于快速完成的场景。因为自旋锁会关闭抢占与中断。

在执行完成之后,在开启中断与抢占。对于不能快速完成,等待时间较长的的场景,不适用于自旋锁。由此引入信号量机制,

而信号量机制的引入的特点,信号量可以使线程进入休眠。比如,对于共享内存。线程A与线程B都要访问,线程A正在访问共享内存期间,

如果线程B试图访问共享内存,如果采用信号量,线程B会进入休眠状态,等到锁被释放之后,休眠的线程B被唤醒,继续执行。如果采用自旋锁,线程B不会休眠,其在就绪状态,等待自旋锁释放。

信号量等待资源进程进入休眠状态,因此适用于资源占用比较久的场合

在中断中不能使用信号量,因为信号量会引起休眠,而中断是不能休眠的。

如果共享资源的持有时间较短,不适合信号量。频繁的休眠,唤醒切换比较占用时间。

信号量数据结构

信号量数据结构在文件:include/linux/semaphore.h

图 1 信号量数据结构

信号量操作的接口函数:

 

 

函数

描述

DEFINE_SEAMPHORE(name)

定义一个信号量,并且设置信号量的值为 1。

void sema_init(struct semaphore *sem, int val)

初始化信号量 sem,设置信号量值为 val。

void down(struct semaphore *sem)

获取信号量,因为会导致休眠,因此不能在中
断中使用。

int down_trylock(struct semaphore *sem);

尝试获取信号量,如果能获取到信号量就获
取,并且返回 0。如果不能就返回非 0,并且
不会进入休眠。

int down_interruptible(struct semaphore *sem)

获取信号量,和 down 类似,只是使用 down 进
入休眠状态的线程不能被信号打断。而使用此
函数进入休眠以后是可以被信号打断的。

void up(struct semaphore *sem)

释放信号量

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

信号量的使用

图 2 信号量的使用流程

如上图所示,信号量的使用流程。先初始化信号量:sema_init。进行信号量减1操作:down。

如果非负,获取临界区资源。执行完成之后,进行加1操作:up。

 

posted @ 2022-07-30 21:28  JwChu  阅读(187)  评论(0编辑  收藏  举报