信号量本质上是一个非负的整数计数器,它被用来控制对公共资源的访问。信号量就是一种睡眠锁。信号量的特点是,如果一个任务试图获取一个已经被占用的信号量,他会被推入等待队列,让其进入睡眠。此刻处理器重获自由,去执行其他的代码。当持有的信号量被释放,处于等待队列的任务将被唤醒,并获取到该信号量。
信号量使用总结:
1、因为信号量可以使等待资源线程进入休眠状态,因此适用于那些占用资源比较久的场合。
2、因此信号量不能用于中断中,因为信号量会引起休眠,中断不能休眠。
3、如果共享资源的持有时间比较短,那就不适合使用信号量了,因为频繁的休眠、切换线程引起的开销要远大于信号量带来的那点优势。
Linux 内核使用 semaphore 结构体表示信号量,结构体内容如下所示:
struct semaphore {
raw_spinlock_t lock;
unsigned int count;
struct list_head wait_list;
};
要想使用信号量就得先定义,然后初始化信号量。有关信号量的 API 函数如下所示:
| 函数 | 描述 |
|---|---|
| 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) | 释放信号量 |
本文详细介绍了信号量在操作系统中的作用,作为资源管理工具,它如何通过计数器控制并发访问。讲解了信号量的使用场景、优缺点,以及Linux内核中的semaphore结构与关键API函数,如DEFINE_SEAMPHORE、sema_init、down系列函数等。

1292

被折叠的 条评论
为什么被折叠?



