信号量,又称信号灯,主要用于进程间以及同一进程不同线程间的同步手段,用来解决进程间的同步与互斥问题的一种进程之间通信机制,包括一个称为信号量的变量和在该变信号量下等待资源的进程等待队列,以及对信号量进行的两个原子操作(PV操作)。其中信号量对应于某一种资源,取一个非负的整型值。信号量的值是指当前可用的资源数量,若它等于0则意味着目前没有可用的资源。
信号灯与其他的进程间通信方式不太相同,因为它主要提供对进程间共享资源访问控制机制,相当于内存中的标志,进程可以根据它判断是否能够访问某些共享资源,但是与此同时,进程也可以修改该标志。所以除了用于访问控制以外,还可以用于进程同步。
使用信号灯的步骤:
1、打开或创建信号灯;
2、信号灯值操作。Linux可以增加或减少信号灯的值,相应于共享资源的释放和占有
3、获得或设置信号灯属性
信号灯API
1、semget函数
功能:配置信号灯
头文件:#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/sem.h>
原型:int semget(key_t key,int nsems,int semflg)
说明:key:键值,由ftok获得,唯一标识一个信号灯集;
nsems:指定打开或新创建的信号灯集中将包含信号灯的数目;
semflg:标志位
返回值:成功,返回信号灯集描述字;失败,返回-1。
注:如果key所代表的信号灯已经存在,且semget指定了IPC_CREAT|IPC_EXCL标志,那么即使参数nsems与原来的信号灯的数目不等,返回的也是EEXIST错误;如果semget只指定了IPC_CREAT标志,那么参数nsems必须与原本的值一致。
2、semop函数
功能:信号灯处理
头文件:#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/sem.h>
原型:int semop(int semid,struct sembuf *sops,unsigned nsops)
说明:semid:信号灯集ID
sops:指向数组的每一个sembuf结构都刻画一个在特定信号灯上的操作
nsops:sops指向数组的大小
sembuf的结构:
struct sembuf
{
unsigned short sem_num;
short sem_op;
short sem_flg;
};
返回值:成功,返回0;失败,返回-1。
3、semctl函数
功能:控制信号灯
头文件:#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
原型:int semtcl(int semid,int semnum,int cmd,union semun arg)
说明:semid:信号灯集
cmd:指定具体的操作类型
所指的操作:
IPC_STAT:获得信号灯信息,信息由arg.buf返回
IPC_SET;设置信号灯信息,待设置信息保存在arg.buf中
GETALL:返回所有信号灯的值,结果保存在arg.array中,参数semnum被忽略
GETNCNT:返回等待semnum所代表信号灯的值增加的进程数,相当于目前有多少进程在等待semnum代表的信号灯所代表的共享资源
semnum指定对哪个信号灯操作,只对几个特殊的cmd操作有意义
arg:设置或返回信号灯信息