一、信号量介绍
信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用的一种设施,是可以用来保证两个或多个关键代码段不被并发
调用。在进入一个关键代码段之前,线程必须获取一个信号量;一旦该关键代码段完成了,那么该线程必须释放信号量。其它想进入该关键代码段的线程必须等待直到第一个线程释放信号量。为了完成这个过程,需要创建一个信号量VI,然后将Acquire Semaphore VI以及Release Semaphore VI分别放置在每个关键代码段的首末端。确认这些信号量VI引用的是初始创建的信号量。
信号量是一个非负整数,所有通过它的进程、现场都会使这个整数-1,当该整数为0时,所有想通过它的进程均需要等待,直到这个整数大于0。
信号量可以看做是一个计数器,在访问临界资源时,通过信号量,保证多进程同步。
每一个进程要访问临界资源时,先申请信号量资源,信号量资源可以被多个进程看到,(信号量也是临界资源),p操作和v操作就是信号量的加或减操作,
二、相关函数
1、semget函数
参数含义:
- key:所创建或打开信号量集的键值
- nsems:创建信号量集中的信号量的个数,该参数仅在创建信号量时有效
- semflg:调用函数的操作类型,也可以用于设置信号量集的访问权限
返回值:成功返回信号量集的IPC标识符,否则返回-1
2、semctl函数
系统调用semctl用来执行在信号量集上的控制操作。和消息队列中的系统调用msgctl类似不过参数不同
参数含义:
semid:信号量集IPC标识符
semnum:操作信号在信号集中的编号
cmd:
·IPC_STAT读取一个信号集量的数据结构semid_ds,并将其存储在semun中的buf参数中。
·IPC_SET设置信号量集的数据结构semid_ds中的元素ipc_perm,其值取自semun中的buf参数。
·IPC_RMID将信号量集从内存中删除。
·GETALL用于读取信号量集中的所有信号量的值。
·
GETNCNT返回正在等待资源的进程数目。
·GETPID返回最后一个执行semop操作的进程的PID。
·GETVAL返回信号量集中的一个单个的信号量的值。
·GETZCNT返回这在等待完全空闲的资源的进程数目。
·SETALL设置信号量集中的所有的信号量的值。
·SETVAL设置信号量集中的一个单独的信号量的值。
第四个蚕食是一个联合类型的副本
返回值
成功,则为一个整数,失败返回-1
3、semop函数
功能:操作一组或一个信号量。
信号量的值与对应资源的使用情况有关,当它大于0,表示当前可用的资源数的数量;当它的值小于0时表示等待使用该资源的进程个数。信号量的值仅能由PV改变
参数:
smid:信号集的识别码,semget函数获取
sops:指向存储信号操作结构的数组指针其操作结构原型如下
其中:sem_num是操作信号在信号集中的编号,第一个信号的编号是0
sem_op:若为正数,该值会加到现有的信号内含值中,通常用于释放资源的使用权;
如果sem_op的值为负数,而其绝对值又大于信号的现值,操作将会阻塞,直到信号值大于或等于sem_op的绝对值。通常用于获取资源的使用权;如果sem_op的值为0,如果没有设置IPC_NOWAIT,则调用该操作的进程或者线程将暂时睡眠,直到信号量的值为0;否则,进程或者线程不会睡眠,函数返回错误EAGAIN。、
sem_flg:信号操作标志
返回值
成功返回0,时报返回-1