linux信号量与完成量

时间:2023-03-09 18:05:53
linux信号量与完成量

信号量:

   是用于保护临界区的一种常用方法,它的使用和自旋锁类似。与自旋锁相同,只有得到信号量的进程才能执行

临界区的代码。但是与自旋锁不同的是,当获取不到信号量时,进程不会原地打转而是进入休眠等待

状态。

#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的值设为最大, 然后唤醒所有等待该完成量的进程