linux信号量与完成量

时间:2022-04-07 15:14:42
信号量:
   是用于保护临界区的一种常用方法,它的使用和自旋锁类似。与自旋锁相同,只有得到信号量的进程才能执行
临界区的代码。但是与自旋锁不同的是,当获取不到信号量时,进程不会原地打转而是进入休眠等待
状态。
#include <linux/semaphore.h>


struct semaphore {
raw_spinlock_t          lock;
unsigned int            count;
struct list_head        wait_list;
};


定义一个信号量:
struct semaphore sem;


初始化信号量:
void sema_init(struct semaphore *sem, int val);  //val为count的初始值
//初始化为1
#define init_MUTEX(sem) sema_init(sem, 1)
        //初始化信号量,并将信号量sem的值设置为0,就是在创建时就处于已锁定的状态
#define init_MUTEX_LOCKED(sem) sema_init(sem, 0)


定义并初始化:
DECLARE_MUTEX(sem);  //count的初始值为1




锁定信号量:
void down(struct semaphore *sem);//获得信号量,可能导致睡眠,不能再中断上下文中使用该函数


int down_interruptible(struct semaphore *sem);
返回非0值表示被信号(不是被UP)唤醒, if(down_interruptible(&sem) return -ERESTARTSYS;

int down_trylock(struct semaphore *sem);//尝试获取信号量sem
返回非0表示没有获取锁


if(count的值大于0)
将count减1后立即返回
else
进入睡眠, down_trylock不会进入睡眠


释放信号量:
void up(struct semaphore *sem);//释放信号量sem,实质上是把sem的值加1


count的值加1


if(有进程等待该信号量)
唤醒第一个等待该信号量的进程

完成量:
#include <linux/completion.h>


struct completion {
unsigned int done;
wait_queue_head_t wait;
}


定义:
struct completion com;


初始化:
init_completion(&com);
done的初始值为0


定义并初始化:
DECLARE_COMPLETION(com);
done的初始值为0


等待完成量:
void wait_for_completion(struct completion *com);
int wait_for_completion_interruptible(struct completion *com);
返回-ERESTARTSYS表示被信号唤醒, 0 completion


if(done的值不等于0)
将done减1后立即返回
else
进入睡眠


唤醒完成量:
void complete(struct completion *com);
将done的值加1, 然后唤醒第一个等待该完成量的进程

void complete_all(struct completion *com);
将done的值设为最大, 然后唤醒所有等待该完成量的进程