5 信号量
信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用的一种设施,是可以用来保证两个或多个关键代码段不被并发调用。
- 背景
数据竞争
- 作用:
控制多进程共享资源的访问(资源有限并且不共享)
- 本质
任一时刻只能有一个进程访问临界区(代码),数据更新的代码。
- 基本操作:PV
原子操作操作也被成为PV原语(P来源于Dutchproberen"测试",V来源于Dutchverhogen"增加")

- 信号
分类 |
取值 |
P(信号量) |
0 :挂起进程;>0 :减1 |
V(信号量) |
0 :恢复进程;>0 :加1 |
- POSIX信号量
查看:man sem_overview
5.1 接口
- 头文件:
semaphore.h
- 库:
pthread
- 分类
信号量分为命名信号量(基于文件)与匿名信号量(基于内存)两种。
5.2 命名信号量/基于文件
操作 |
函数 |
创建 |
sem_t *sem_open(const char *name, int oflag, mode_t mode,unsigned int value) |
删除 |
int sem_unlink(const char *name) |
打开 |
sem_t *sem_open(const char *name, int oflag) |
关闭 |
int sem_close(sem_t *sem) |
挂出 |
int sem_post(sem_t *sem) |
等待 |
int sem_wait(sem_t *sem) |
尝试等待 |
int sem_trywait(sem_t *sem) |
获取信号量的值 |
int sem_getvalue(sem_t *sem, int *sval) |
5.2.1创建
sem_t *sem_open(const char *name, int oflag, mode_t mode,unsigned int value)
参数 |
含义 |
name |
信号量IPC名字 |
oflag |
标志 |
mode |
权限位 |
value |
信号量初始值 |
返回值 |
含义 |
非SEM_FAILED |
信号量的指针 |
SEM_FAILED |
出错 |
5.2.2 删除
int sem_unlink(const char *name)
5.2.3 打开
sem_t *sem_open(const char *name, int oflag)
参数 |
含义 |
name |
信号量IPC名字 |
oflag |
标志 |
返回值 |
含义 |
非SEM_FAILED |
信号量的指针 |
SEM_FAILED |
出错 |
5.2.4 关闭
int sem_close(sem_t *sem)
5.2.5 挂出
int sem_post(sem_t *sem)
5.2.6 等待
int sem_wait(sem_t *sem)
5.2.7 尝试等待
int sem_trywait(sem_t *sem)
5.2.8 获取信号量的值
int sem_getvalue(sem_t *sem, int *sval)
参数 |
含义 |
sem |
信号量的指针 |
sval |
信号量的值 |
5.3 匿名信号量/基于内存
操作 |
函数 |
初始化 |
int sem_init (sem_t *sem , int pshared, unsigned int value) |
销毁 |
int sem_destroy(sem_t *sem) |
挂出 |
int sem_post(sem_t *sem) |
等待 |
int sem_wait(sem_t *sem) |
尝试等待 |
int sem_trywait(sem_t *sem) |
获取信号量的值 |
int sem_getvalue(sem_t *sem, int *sval) |
注:其中挂出和等待操作与命名信号量相同。
5.3.1 初始化
int sem_init (sem_t *sem , int pshared, unsigned int value)
参数 |
含义 |
sem |
信号量的指针 |
pshared |
共享方式。0:线程间共享;1:进程间共享,需要共享内存 |
value |
信号量初始值 |