有名信号量(信号灯)-----用以控制共享资源
步骤:建立key值->由key值创立信号量->销毁信号量
创建key值:使用ftok获得key值
根据key值得到信号量:semget
int semget(key_t key,int a,int semflg)
参数:a:创建的信号量个数
semflg:IPC_CREAT 对象不存在就创建
返回信号量ID
销毁信号量:semctl
int semctl(int semid ,int semnum,int cmd,...);
向信号量发送命令
参数:
semid:信号的id号
semnum:具体操作信号量的编号
cmd:
IPC_RMID 删除信号灯
SETVAL 设置信号量的值
初始化:--------该共用体需要自己定义
union semun {
int val; /* Value for SETVAL */
struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
unsigned short *array; /* Array for GETALL, SETALL */
struct seminfo *__buf; /* Buffer for IPC_INFO
(Linux-specific) */
};
释放信号量
semop
int semop(int semid, struct sembuf *sops, size_t nsops);
功能:
对信号量完成操作
参数:
semid:信号灯的ID号
sops:信号量操作的数组首地址
nsops:数组元素个数
返回值:
成功返回0
失败返回-1
函数内自带一个结构体strutc sembuf
该结构体内容为:
unsigned short sem_num; /* semaphore number */ 操作信号量的下标
short sem_op; /* semaphore operation */ 具体对信号量的操作(申请:-1 释放:+1)
short sem_flg; /* operation flags */ SEM_UNDO
例子:
#include "head.h"
union semun {
int val; /* Value for SETVAL */
struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
unsigned short *array; /* Array for GETALL, SETALL */
struct seminfo *__buf; /* Buffer for IPC_INFO
(Linux-specific) */
};
int main(void)
{
key_t key;
int semid = 0;
union semun myun;
struct sembuf mybuf;
int ret = 0;
key = ftok(".", 'a');
semid = semget(key, 2, IPC_CREAT | 0664);
/* 对信号灯中的0号信号量初始化为0 */
myun.val = 0;
semctl(semid, 0, SETVAL, myun);
/* 对信号灯中的1号信号量初始化为1 */
myun.val = 1;
semctl(semid, 1, SETVAL, myun);
/* 申请1号信号量 */
mybuf.sem_num = 1;
mybuf.sem_op = -1;
mybuf.sem_flg = SEM_UNDO;
ret = semop(semid, &mybuf, 1);
if (-1 == ret)
{
perror("fail to semop");
return -1;
}
printf("申请到写信号量!\n");
/* 释放0号信号量 */
mybuf.sem_num = 0;
mybuf.sem_op = +1;
mybuf.sem_flg = SEM_UNDO;
ret = semop(semid, &mybuf, 1);
if (-1 == ret)
{
perror("fail to semop");
return -1;
}
printf("释放了读信号量!\n");
/* 申请0号信号量 */
mybuf.sem_num = 0;
mybuf.sem_op = -1;
mybuf.sem_flg = SEM_UNDO;
ret = semop(semid, &mybuf, 1);
if (-1 == ret)
{
perror("fail to semop");
return -1;
}
printf("申请了读信号量!\n");
semctl(semid, 0, IPC_RMID);
return 0;
}