信号量(又名信号灯):与其他进程间通信方式不大相同,它主要提供对进程间共享资源访问控制机制,主要用途是保护临界资源,相当于内存中的标志,进程可以根据它判断是否能够访问某些共享资源,同时,进程也可以修改标志,除了用于访问控制外,还可用于进程同步,即信号量还可以保护进程间的同步互斥。
同步:按一定的顺序去执行
互斥:某一进程占用资源,释放后其他进程才能使用。
信号量可分为这两类:
1、二值信号灯:信号灯的值只能取0或1,类似于互斥锁。 但两者有不同:
信号灯强调共享资源,只要共享资源可用,其他进程同样可以修改信号灯的值;
互斥锁更强调进程,占用资源的进程使用完资源后,必须由进程本身来解锁
2、计数信号灯:信号灯的值可以取任意非负值
一个信号函数应具备以下几个顺序:
1.创建打开信号量,semget()
2.初始化信号量,semctl()的SETVAL操作。当使用二维信号量时将信号量初始化为1;
3. 进行信号量的PV操作,调用semop()函数。
4.如果不用信号量,从系统中删除他/她,使用semctl的IPC_RMID操作。
信号量的同步和互斥PV
Semget()
函数的作用:创建信号量
函数的原型:int semget(key_t key, int nsems, int semflg);
函数的头文件:#include<sys/sem.h>、#include<sys/types.h>、#include<sys/ipc.h>
函数各参数的作用:
Key:键值
Nsems:信号量的数目,通常取1个
Semflg:同open一样的权限
函数的返回值:
成功:返回信号量的标识符
出错:返回 -1.
Semctl()
函数的作用:信号量的控制、初始化、删除
函数的原型:int semctl(int semid, int semnum, int cmd, union semun arg);
函数各参数作用:
Semnum:通常为0,表第一个信号量
Cmd:
IPC_STAT
IPC_SETVAL:设置为arg中的val值
IPC_GETVAL:获取信号量的值
IPC_RMID:删除信号量
函数的返回值:
成功:cmd不同的值返回值不一样
IPC_STAT、IPC_SETVAL、IPC_RMID返回值为0
IPC_GETVAL:返回信号量的值
出错:返回 -1
Semop()
函数的作用:执行PV操作
函数的原型:int semop(int semid, struct sembuf *sops, size_t nsops);
函数各参数作用:
Semid:信号灯集的ID
Struct sembuf *sops;
Sem_op:-1, 执行P操作; +1, 执行V操作
Nsops:表sops指向数组的大小
函数的返回值:
成功:返回信号量标识符
出错:返回 -1