1 #include <sys/sem.h>
2 // 创建或获取一个信号量组:若成功返回信号量集ID,失败返回-1
3 int semget(key_t key, int num_sems, int sem_flags);
当semget创建新的信号量集合时,必须指定集合中信号量的个数(即num_sems),通常为1;
如果是引用一个现有的集合,则将num_sems指定为 0 。
4 // 对信号量组进行操作,改变信号量的值:成功返回0,失败返回-1
5 int semop(int semid, struct sembuf semoparray[], size_t numops);
struct sembuf
{
short sem_num; // 信号量组中对应的序号,0~sem_nums-1
short sem_op; // 信号量值在一次操作中的改变量
short sem_flg; // IPC_NOWAIT, SEM_UNDO
}
6 // 控制信号量的相关信息
7 int semctl(int semid, int sem_num, int cmd, ...);
SETVAL:用于初始化信号量为一个已知的值
IPC_RMID:删除一个信号量集合
#include <iostream>
#include <sys/types.h>
#include <sys/sem.h>
#include <unistd.h>
// 联合体 用于semctl初始化
union semun {
int val; //for SETVAL
struct semid_ds *buf;
unsigned short *array;
};
// 初始化信号量
int init_sem(int sem_id,int value)
{
union semun tmp;
tmp.val = value;
if(semctl(sem_id,0,SETVAL,tmp) == -1)
{
perror("Init Semaphore Error");
return -1;
}
return 0;
}
// P操作
int sem_p(int sem_id)
{
struct sembuf sbuf;
sbuf.sem_num = 0; // 序号
sbuf.sem_op = -1; // P操作
sbuf.sem_flg = SEM_UNDO;
if(semop(sem_id,&sbuf,1) == -1)
{
perror("P operation Error");
return -1;
}
return 0;
}
// V操作
int sem_v(int sem_id)
{
struct sembuf sbuf;
sbuf.sem_num = 0;
sbuf.sem_op = 1;
sbuf.sem_flg = SEM_UNDO;
if(semop(sem_id,&sbuf,1) == -1)
{
perror("V operation Error");
return -1;
}
return 0;
}
// 删除信号量集
int del_sem(int sem_id)
{
union semun tmp;
if(semctl(sem_id,0,IPC_RMID,tmp) == -1)
{
perror("Delete Semaphore Error");
return -1;
}
return 0;
}
int main()
{
int sem_id; // 信号量集ID
key_t key;
pid_t pid;
// 获取key值
if((key = ftok(".",‘z‘)) < 0)
{
perror("ftok error");
exit(1);
}
// 创建信号量集,其中只有一个信号量
if((sem_id = semget(key,1,IPC_CREAT|0666)) == -1)
{
perror("semget error");
exit(1);
}
// 初始化: 初值设为0资源被占用
init_sem(sem_id,0);
if((pid=fork()) < 0)
{
perror("fork");
}else if(pid == 0)
{
sleep(2);
printf("Process child: pid=%d\n",getpid());
sem_v(sem_id);
del_sem(sem_id);
// 父进程
}
return 0;
信号量