#ifndef _SEM_H_
#define _SEM_H_
#include<myhead.h>
//信号灯集的申请,初始化信号灯,并返回信号灯集的id
int create_sem(int semcount);
//申请信号灯资源操作 P操作 -1
int P(int semid,int semno);
//释放信号灯资源操作 V操作 +1
int V(int semid ,int semno);
//删除信号灯集
int del_sem(int semid);
#endif
#include<myhead.h>
#include"sem.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 init_sem(int semid,int i)
{
int val = -1;
printf("请输入第%d个的val值:",i);
scanf("%d",&val);
union semun su;
su.val = val;
if(semctl(semid,i,SETVAL,su) == -1)
{
perror("semctl");
return -1;
}
}
//信号灯集的申请,初始化信号灯,并返回信号灯集的id
int create_sem(int semcount)
{
//1、创建key值
key_t key = ftok("/",'k');
if(key == -1)
{
perror("ftok");
return -1;
}
//2、通过key值创建一个信号灯集
int semid = semget(key,semcount,IPC_CREAT|IPC_EXCL|0664);
if(semid == -1)
{
if(errno == EEXIST)
{
semid = semget(key,semcount,IPC_CREAT);
return semid;
}
perror("semget");
return -1;
}
//3、给信号灯集中的信号等进行初始化操作
for(int i =0;i<semcount;i++)
{
init_sem(semid,i);
}
//4、返回信号灯集的id
return semid;
}
//申请信号灯资源操作 P操作 -1
int P(int semid,int semno)
{
struct sembuf buf;
buf.sem_num = semno;
buf.sem_op = -1;
buf.sem_flg = 0;
if(semop(semid,&buf,1) == -1)
{
perror("semop P");
return -1;
}
return 0;
}
//释放信号灯资源操作 V操作 +1
int V(int semid ,int semno)
{
struct sembuf buf;
buf.sem_num = semno;
buf.sem_op = 1;
buf.sem_flg = 0;
if(semop(semid,&buf,1) == -1)
{
perror("semop V");
return -1;
}
return 0;
}
//删除信号灯集
int del_sem(int semid)
{
if(semctl(semid,0,IPC_RMID,0)== -1)
{
perror("semctl aa");
return -1;
}
}
#include <myhead.h>
#include "sem.h"
#define SIZE_PAGE 4096
int main(int argc, const char *argv[])
{
//定义一个变量存放pid
int pid1 = -1,pid2 = -1;
//1.创建信号灯集
int semid = create_sem(3);
if(semid == -1)
{
perror("create error");
return -1;
}
//创建子进程1
pid1 = fork();
if(pid1 == 0)
{
int count = 0;
//子进程1
while(count <5 )
{
count++;
P(semid,0); //申请0号灯资源
sleep(1);
printf("B");
fflush(stdout);
V(semid,1); //释放1号灯资源
}
//退出子进程1
exit(EXIT_SUCCESS);
}else if(pid1 > 0)
{
//创建子进程2
pid2 = fork();
if(pid2 == 0)
{
int count = 0;
//子进程2
while(count < 5)
{
count++;
P(semid,1); //申请1号灯资源
sleep(1);
printf("C\n");
V(semid,2); //释放2号灯资源
}
//退出子进程2
exit(EXIT_SUCCESS);
}else if(pid2 > 0)
{
int count = 0;
//父进程
while(count < 5)
{
P(semid,2); //申请2号灯资源
sleep(1);
printf("A");
fflush(stdout);
V(semid,0); //释放0号灯资源
count ++;
}
//回收子进程
wait(NULL);
wait(NULL);
//删除信号灯资源
del_sem(semid);
return 0;
}else
{
perror("fork pid2 error");
return -1;
}
}else
{
perror("fork pid1 error");
return -1;
}
return 0;
}