10.1 概述
- posix有名信号量:使用posix IPC标识,可用于进程或线程之间的同步
- posix基于内存的信号量:放在共享内存去中,可用于进程或线程之间的同步
- System V信号量:在内核中维护,可用于进程或线程之间的同步
P/V操作
- P操作:代表荷兰语单词proberen(尝试),也称递减或上锁,posix术语叫等待
- V操作:代表荷兰语单词verhogen(增加),也称递增或解锁或发信号,posix术语叫挂出
互斥锁、条件变量和信号量之间的差别
- 互斥锁必须总是由给他上锁的线程解锁,信号量的挂出却不必由执行过它的等待操作的同一线程执行
- 互斥锁呈二值状态
- 既然信号量有一个与之关联的状态,那么信号量的挂出操作总是被记住
- 能够从信号处理程序中安全调用的唯一函数是sem_post()
10.2 sem_open()、sem_close()、sem_unlink()函数
#include <fcntl.h> /* For O_* constants */
#include <sys/stat.h> /* For mode constants */
#include <semaphore.h>
sem_t *sem_open(const char *name, int oflag);
sem_t *sem_open(const char *name, int oflag,mode_t mode, unsigned int value);
- oflag:如果指定了O_CREAT,那参数三和四就是必须的,信号量尚未存在就初始化它
- O_CREAT|O_EXCL(独占):信号量已存在会出错
- mode:指定权限位
value:指定信号量的初始值
使用sem_open()打开的信号量使用sem_close()关闭,进程结束时会自动执行
#include <semaphore.h>
int sem_close(sem_t *sem);
Posix信号量至少是随内核持续的
,可用下面的函数删除,每个信号量有一个引用计数器记录当前的打开次数
,引用计数大于0时,name就能从文件系统中删除
#include <semaphore.h>
int sem_unlink(const char *name);
Link with -pthread.
10.3 sem_wait()和sem_trywait()函数
#include <semaphore.h>
int sem_wait(sem_t *sem);//被中断返回EINTR
int sem_trywait(sem_t *sem);//失败返回EAGAIN
int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);
10.4sem_post()和sem_getvalue()函数
#include <semaphore.h>
int sem_post(sem_t *sem);
int sem_getvalue(sem_t *sem, int *sval);
- sval:当前信号量的值
- 0:信号量已经上锁
- 负数:绝对值表示等待信号量解锁的线程数