进程间通信之3----信号量
1、信号量
信号量分为以下三种。
1、System V 信号量,在内核中维护,可用于进程或线程间的同步,常
用于进程的同步。
2、Posix 有名信号量,
可用于进程或线程间的同步, 常用于线程。
3、Posix 基于内存的信号量,存放在共享内存区中,可用于进程或线程
间的同步。
为了获得共享资源进程需要执行下列操作:
(1)测试控制该资源的信号量。
(2)若信号量的值为正,则进程可以使用该资源。进程信号量值减
1,表示它使用了一个
资源单位。此进程使用完共享资源后对应
的信号量会加 1。以便其他进程使用。
(3)若信号量的值为0,则进程进入休息状态,直至信号量值大于
0。进程被唤醒,返回第
(1)步。
函数原型:
#include <sys/sem.h>
#include <sys/ipc.h>
#include <sys/types.h>
int semget(key_t key,int nsems,int flag);
int semop(int semid,struct sembuf *sops,size_t num_sops);
int semctl(int semid, int semnum, int cmd, …);
- 函数semget创建一个信号量集或访问一个已存在的信号量集。 返回值:成功时,返回一个称为信号量标识符的整数,semop 和 semctl 会使用它;出错时,返回-1。
- 参数 key 是唯一标识一个信号量的关键字,如果为 IPC_PRIVATE(值为0,创建一个只有创建者进程才可以访问的信号量, 通常用于父子进程之间;非0值的key,表示创建一个可以被多个进程共享的信号量。
- 参数flag是一组标志,还可以与键值IPC_CREAT按位或操作,以创建一个新的信号量。也可以通过 IPC_CREAT 和 IPC_EXCL标志的联合使用确保自己将创建出一个新的独一无二的信号量。
- 函数 semop 用于改变信号量对象中各个信号量的状态。返回值:成功时,返回 0;失败时,返回-1.参数 semid 是由 semget 返回的信号量标识符。参数sops是指向一个结构体数组的指针。每个数组元素至少包含以下几个成员:
- struct sembuf{
-
- short sem_num; //操作信号量在信号量集合中的编号, 第一个信号量的编号是 0。
- short sem_op; //sem_op 成员的值是信号量在一次操作中需要改变的数值。通常只会用到两个值,一个是-1, 也就是 p 操作,它等待信号量变为可用;一个是+1,也就是 v 操作,它发送信号通知信号量现在可用。
- short sem_flg; //通常设为:SEM_UNDO,程序结束, 信号量为semop调用前的值。
- };
- 参数 nops为sops指向的sembuf结构体数组的大小。函数 semctl 用来直接控制信号量信息。参数 semid 是由 semget 返回的信号量标识符。参数 semnum 为集合中信号量的编号, 当要用到成组的信号量时,从0开始。一般取值为0,表示这是第一个也是唯一的一个信号量。参数cmd为执行的操作。通常为:IPC_RMID(立即删除信号集,唤醒所有被阻塞的进程)、 GETVAL(根据semun返回信号量的值,从0 开始,第一个信号量编号为0)、SETVAL(根据 semun 设定信号的值,从0开始,第一个信号量编号为0)、GETALL(获取所有信号量的值, 第二个参数为0,将所有信号的值存入semun.array中)、SETALL(将所有 semun.array的值设定到信号集中,第二个参数为 0)等。