#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、返回信号灯集的idreturn 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[])
{//定义一个变量存放pidint pid1 = -1,pid2 = -1;//1.创建信号灯集int semid = create_sem(3);if(semid == -1){perror("create error");return -1;}//创建子进程1pid1 = fork();if(pid1 == 0){int count = 0;//子进程1while(count <5 ) { count++;P(semid,0); //申请0号灯资源sleep(1);printf("B");fflush(stdout);V(semid,1); //释放1号灯资源}//退出子进程1exit(EXIT_SUCCESS);}else if(pid1 > 0){//创建子进程2pid2 = fork();if(pid2 == 0){int count = 0;//子进程2while(count < 5){count++;P(semid,1); //申请1号灯资源sleep(1);printf("C\n"); V(semid,2); //释放2号灯资源}//退出子进程2exit(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;
}