1. 信号量
(1)概念
信号量(又名:信号灯)与其他进程间通信方式不大相同,主要用途是保护临界资源.
进程可以根据它判定是否能够访问某些共享资源。除了用于访问控制外,还可用于进程同步。
(2)分类
二值信号灯:信号灯的值只能取0或1,类似于互斥锁。 但两者有不同:
信号灯强调共享资源,只要共享资源可用,其他进程同样可以修改信号灯的值;
互斥锁更强调进程,占用资源的进程使用完资源后,必须由进程本身来解锁。
计数信号灯:信号灯的值可以取任意非负值
(3)步骤
a) 创建打开信号量,semget()
b) 初始化信号量,semctl()SETVAL操作。使用二维信号量时将信号量初始化为1;
c) 进行信号量的PV操作,调用semop()函数。
d) 如果不用信号量,从系统中删除他/她,使用semctl的IPC_RMID操作。
2. 内核实现信号灯的原理及其API函数
(1)semget
函数的作用:创建信号量
函数的原型:int semget(key_t key,int nsems,int semflg);
函数的参数:nsems:创建信号量的数目,通常取1个
semflg:同open一样的权限
返回值:成功:信号量的标识符;出错:-1
(2)semctl
函数的作用:信号量的控制:初始化、删除等
函数的原型:int semctl(int semid,int semnum,int gmd,union semun arg);
函数的参数:semnum:通常为0,第一个信号量
cmd:IPC_STAT:获取结构量
IPC_SETVAL:设置为arg中的val值
IPC_GETVAL:获取信号量的值
IPC_RMID:从系统中删除信号量
arg:union semun结构
返回值:cmd不同的返回值不同
IPC_STAT、IPC_SETVAL、IPC_RMID、返回值为0;IPC_GETVAL:返回信号量的值;出错为-1
(3)semop
函数的作用:执行PV操作
函数的原型:int semop(int semid,struct sembuf * sops,size_t nsops);
函数的参数:semid:semget()函数返回的信号量标识符
sops:指向信号量操作数组
struct sembuf *sops;
sem_op:-1为P操作;+1为V操作
nsops:操作信号量的个数
返回值:成功:信号量标识符;出错:-1
3. 如何使用信号灯来实现进程间的同步与互斥?
信号量的同步和互斥PV(见下例)
sem1.c
sem2.c
运行结果: