1、信号量的定义
struct semaphore {
spinlock_t lock;
unsigned int count;
struct list_head wait_list;
}
lock是一个自旋锁,保证对count操作时的原子性。
count表示可以同时获得信号量而进入临界区的执行路径的个数。
wait_list是一个双向链表,用来管理睡眠在该信号量上的进程。
2、信号量的初始化
sema_init(struct * semaphore , int val) 对信号两进行初始化
先把semaphore的lock设置为解锁状态,然后把count设置为val ,然后初始化wait_list链表头。
3、DOWN操作
可用函数:
void down(struct semaphore * sem) ;
int down_interruptible(struct semaphore * sem) ;
int down_killable(struct semaphore * sem) ;
int down_trylock(struct semaphore * sem) ;
int down_timeout(struct semaphore *sem , long jiffies) ;
对于 down 操作,如果执行路径能获得信号量,则将sem->count + 1;
如果不能获得该信号量,则将进程加入wait_list队列,进程睡眠,不可被信号中断。
对于 down_interruptible 操作,如果执行路径能获得该信号量,则将 sem->count + 1;
如果不能获得该信号量,则进程加入wait_list链表并进入睡眠,进程状态为TASK_INTERRUPTIBLE。
对于 down_killable 操作,如果执行路径获得该信号量,则count + 1;
如果不能获得该信号量,则进程加入wait_list链表并睡眠,可以被fatal signal唤醒。
对于 down_trylock 操作,如果无法获得该信号量则直接返回1,否则获得信号量返回0;
对于down_timeout 操作,如果无法获得信号量则进入睡眠,如果在jiffies的时间内还没有被唤醒,则返回错误码;
4、UP 操作
void up (struct semaphore * sem)
up操作:
如果该信号量sem的wait_list链表为空,则 sem->count + 1。
如果wait_list不为空,则将链表的第一个节点删除,并将其唤醒。
5、用信号量semaphore来完成互斥机制
将count = 1。
DECLARE_MUTEX(name)来定义一个互斥机制的信号量。
读取者与写入者信号量 RWSEM
1、读写信号量的定义
struct rw_semaphore {
__s32 activity;
spinlock_t wait_lock;
struct list_head wait_list;
}
activity = 0, 当前信号量上没有任何活动的读取者或者写入者;
activity = -1,当前该信号量上有一个活动的写入者;
activity = n,当前该信号量上有n个活动的读取者。
2、初始化
DECLARE_RWSEM 静态初始化
init_rwsem 动态初始化
3、读取者的DOWN
void __sched down_read(struct rw_semaphore * sem);
int down_read_trylock(struct rw_semaphore *sem)
4、读取者的UP
void up_read(struct rw_semaphore *sem)
5、写入者的DOWN
void __sched down_write(struct rw_semaphore *sem)
6、写入者的UP
void up_write(struct rw_semaphore *sem)