首先,信号量分为内核信号量和用户进程信号量。
一、内核信号量
相关的函数为:
(1)初始化:
void sema_init (struct semaphore *sem, int val);
void init_MUTEX (struct semaphore *sem); //将sem的值置为1,表示资源空闲
void init_MUTEX_LOCKED (struct semaphore *sem); //将sem的值置为0,表示资源忙
(2)申请内核信号量所保护的资源:
void down(struct semaphore * sem); // 可引起睡眠
int down_interruptible(struct semaphore * sem); // down_interruptible能被信号打断
int down_trylock(struct semaphore * sem); // 非阻塞函数,不会睡眠。无法锁定资源则
马上返回
(3)释放内核信号量所保护的资源: void up(struct semaphore * sem);
二、用户态信号量
用户态信号量又分为System V信号量与Posix信号量。其中,POSIX信号量又分为有名信号量与无名信号量,有名信号量存在文件中,无名信号量存在内存中,Linux中只实现了无名信号量。System V信号量常用于进程同步,是一个或多个信号量的集合,所属头文件<sys/sem.h>,使用复杂;Posix信号量常用于线程同步,所属头文件<semaphore.h>,使用简单。
System V与Posix信号量函数清单如下:
Systm V | POSIX |
semctl() | sem_getvalue() |
semget() | sem_post() |
semop() | sem_timedwait() |
sem_trywait() | |
sem_wait() | |
无名信号量如下: | |
sem_init() | |
sem_destroy() | |
有名信号量如下: | |
sem_close() | |
sem_open() | |
sem_unlink() |
其中,POSIX 无名信号量的2个函数原型如下:
int sem_init(sem_t *sem,int pshared,unsigned int value);
int sem_destroy(sem_t *sem);
此处sem_init有3个参数,与内核中的不同,pshared为信号量最多由几个进程共享。Linux中只能取0。value一般为1,表示资源可用,为0表示不可用。