信号量
当我们在多用户系统,多进程系统,或是两者混合的系统中使用线程操作编写程序时,我们经常会发现我们有段临界代码,在此处我们需要保证一个进程(或是一个线程的执行)需要排他的访问一个资源。
为了解决这个问题,引用了信号量机制,我们可以使用互斥或信号量来控制一个多线程程序对于临界区的访问。
信号量是一个特殊的变量,他是一个整数,并且只有两个操 作可以使得其值增加:等待(wait)与信号(signal)。
用于等待(wait)的P(信号量变量)
用于信号(signal)的V(信号量变量)
二值信号量
二值信号量使是只有0和1两个值的变量
假如有一个信号量为mutex,有如下两个操作
- P(mutex)/wait(mutex) 若mutex大于0,mutex减为0;若mutex等于0,则挂起该进程
- V(mutex)/signal(mutex) 若有进程被挂起等待mutex则释放mutex使被挂起的进程执行,若没有,则mutex加到1
也叫互斥信号量,可以用其管理临界区资源的控制权
Linux中的信号量工具
信号量函数
信号量函数定义:
1 |
|
这些函数用于操作信号量值数组
semget函数
semget的作用: 创建一个新信号量 或者 取得一个已有的信号量
1 | int semget(key_t key, int num_sems, int sem_flags); |
key是整数值(唯一非零),可以任意指定一个正整数,semget可以根据key,新创建一个信号量,返回改信号量的标识,不相关的进程可以通过它访问这个创建的信号量,代表程序可能会使用某个资源.如果在两个进程中使用相同的key则key将负责两个进程的协调工作.
PS:
同一个key值返回的信号量标识相同
不同的key值会创建不同的信号量,且信号量之间没有任何关系
num_sems表示需要的信号量数目,一般为1
sem_flags是一组标志,与fopen函数的 “w” “b” “r”类似,最低的9位二进制数字代表了这个信号量的权限信息.如IPC_CREATE | 0666,这些标记可以与 IPC_CREAT进行或操作来创建新的信号量,同时又可以用于取一个已有的信号量,使用IPC_CREAT | IPC_EXCL 来确保新建信号量,如果信号量已经有了会返回错误。
PS:
IPC_CREAT 如果共享内存不存在,则创建一个共享内存,否则打开操作。
IPC_EXCL 只有在共享内存不存在的时候,新的共享内存才建立,否则就产生错误。
semget函数成功返回一个相应信号量标识符(非0),失败返回-1.
semop函数
semop函数用于对信号量进行操作。
1 | int semop(int sem_id, struct sembuf *sem_opa, size_t num_sem_ops); |
- sem_id,表示对哪一个信号量进行操作,由semget函数返回
- sembuf *sem_ops
1 | struct sembuf { |
- size_t num_sem_ops表示操作次数一般为1
semctl函数
semctl用于直接控制信号量的信息,例如初始化一个值或删除信号量。
1 | int semctl(int sem_id, int sem_num, int command, ...); |
sem_id,表示对哪一个信号量进行操作,由semget函数返回
sem_num,要处理的信号量的下标,即指定对哪个信号灯进行操作(0,1,2…)若为二值信号量则为0
command,表示要执行的动作
- SETVAL:用于初始化信号量为一个已知的值。所需要的值作为联合semun.val成员来传递。在信号量第一次使用之前需要设置信号量。
- IPC_RMID:当信号量不再需要时用于删除一个信号量标识。
union semun
1
2
3
4
5
6
7
8
9union semun{
int val;
struct semid_ds *buf;
unsigned short *array;
};这个声明一般包含在sem.h里面,也有可能没有,没有的话需要自己声明。
根据command的不同,返回值也不同。对于 SETVAL和IPC_RMID 成功返回0 失败返回-1
信号量的使用
创建信号量
1 | int sem_id; |
设置信号量初值
1 | int set_semvalue(int sem_id, int index, int value)//index为信号量中的第几个信号灯 |
删除信号量
1 | void del_semvalue(int sem_id) |
P操作
P操作是通过调用semop函数实现的。
1 | int P(int sem_id, int index) |
V操作
1 | int V(int sem_id, int index) |