信号量 Linux函数semget();semctl();semop();
信号量三个函数
头文件#include<sys/sem.h>
int semget(key_t _key ,int _nsems,int _semflg);
int semctl(int _semid ,int _semnum,int _cmd ……);
int semop(int semid ,struct sembuf *_sops ,size_t _nsops);
semget
int semget(key_t _key ,int _nsems,int _semflg);
- 功能:创建一个新的信号量或获取一个已经存在的信号量的键值。
- 返回值:成功返回信号量的标识码ID。失败返回-1;
参数
- _key:信号集的键值,注意是信号集,一个信号集会包含多个信号量,这个键值用来在多个进程中表示到同一个信号集,跟进程PID类似,如果系统已存在一个信号集的键值,那么申请到的就是同一个信号集
- _nsems:这个信号集里面有多个信号量
- _semflg:
- IPC_CREAT如果信号量不存在,则创建一个信号量,否则获取。
- IPC_EXCL只有信号量不存在的时候,新的信号量才建立,否则就产生错误。
示例
int semid=semget(8888,2,IPC_CREAT|0666);
//创建了一个键值为8888,权限为666的信号集,同时这个信号集包含了两个信号量
semctl
int semctl(int _semid ,int _semnum,int _cmd ……);
- 功能:控制信号量的信息。
- 返回值:成功返回0,失败返回-1;
参数
- _semid:信号集的标志码(ID),也就是
semget()
函数的返回值; - _semnum:信号在信号集中的序号。从0开始排序
- _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设置信号量集中的一个单独的信号量的值。
- Semunion:第4个参数是可选的,一般是
union semun
的实例
这个联合体是需要自己定义的
当union semun { int val; struct semid_ds *buf; unsigned short *arrary; };
_cmd
为设置时,比如_cmd=SETALL
,那么Semunion就是设置信号量的值
当_cmd
为获取时,比如_cmd=GETALL
,那么Semunion就是获取信号量的值
示例代码
如果要设置全部信号量的值
union semun {
int val;
struct semid_ds *buf;
unsigned short *arrary;
};
union semun sem_args;
unsigned short array[3]={1, 2, 4}; //信号集里面信号量的值分别是: 1, 2, 4
sem_args.array = array;
ret = semctl(semid, 0, SETALL, sem_args);//当_cmd=SETALL时,第二个参数是什么都无所谓
if (-1 == ret){
perror("semctl");
exit(EXIT_FAILURE);
}
如果要获取全部信号量的值
union semun sem_args;
unsigned short array[3];
sem_args.array = array;
ret = semctl(semid, 0, GETALL, sem_args);//当_cmd=GETALL时,第二个参数是什么都无所谓
if (-1 == ret){
perror("semctl");
exit(EXIT_FAILURE);
}
//array[]数值分别存储着各个信号量的值,当然是按顺序排好的
semop
int semop(int semid ,struct sembuf *_sops ,size_t _nsops);
- 功能:用户改变信号量的值。也就是使用资源还是释放资源使用权。
- 返回值:成功返回0,失败返回-1;
参数
- semid:信号集的标志码(ID),也就是
semget()
函数的返回值; - _sops是一个指向结构体数组的指针。
struct sembuf{
unsigned short sem_num;//第几个信号量,第一个信号量为0;
short sem_op;//对该信号量的操作。
short semflg;
};
- sem_op:
- sem_op=1:释放信号量,信号量的值+1
- sem_op=-1:等待一个信号量,信号量的值-1
当信号量的值为0时,获取失败信号量失败
- _semflg:
- IPC_NOWAIT:等不到信号量不会阻塞(非阻塞式)
- IPC_UNDO:等不到信号量就阻塞(阻塞式等待)
- nsops:操作结构的数量,恒大于或等于1
示例
struct sembuf sem_b;
sem_b.sem_num = 0; //第0个信号量
sem_b.sem_op = 1; //释放一个信号量,信号量的值+1
sem_b.sem_flg = SEM_UNDO; //不阻塞 当信号量的值为0时,获取信号量失败,阻塞
if(semop(semid, &sem_b, 1) == -1){
fprintf(stderr, "error\n");
return -1;
}
标签:IPC,semid,int,cmd,通信,信号量,linux,sem
From: https://www.cnblogs.com/mybbFHM/p/18173931