#include<head.h>
#include"sem.h"
int main(int argc, const char *argv[])
{
pid_t pid1,pid2;
int semid;
int num=5;
if((pid1=fork())==0)
{
if((semid=init_sem())==-1)
{
printf("init_sem errorr");
return -1;
}
while(num--)
{
P(semid,0);
printf("A");
fflush(stdout);
V(semid,1);
sleep(1);
}
exit(0);
}
else if((pid2=fork())==0)
{
if((semid=init_sem())==-1)
{
printf("init_sem errorr");
return -1;
}
while(num--)
{
P(semid,1);
printf("B");
fflush(stdout);
V(semid,2);
sleep(1);
}
exit(0);
}
else
{
if((semid=init_sem())==-1)
{
printf("init_sem errorr");
return -1;
}
while(num--)
{
P(semid,2);
printf("C");
fflush(stdout);
V(semid,0);
sleep(1);
}
printf("\n");
}
wait(NULL);
wait(NULL);
sem_del(semid);
return 0;
}
#ifndef __SEM_H__
#define __SEM_H__
int init_sem();
int init_semnum_value(int semid,int semnum,int value);
int P(int semid,int semnum); //申请信号灯集的资源
int V(int semid,int semnum); //释放信号灯集的资源
int sem_del(int semid); //删除信号灯集
#endif
#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 init_semnum_value(int semid,int semnum,int value)
{
union semun s;
s.val=value;
if(semctl(semid,semnum,SETVAL,s)<0)
{
perror("semctl error");
return -1;
}
return 0;
}
//创建并初始化一个信号灯集
int init_sem()
{
key_t key;
if((key=ftok("./",'q'))<0)
{
perror("ftok error");
return -1;
}
//创建信号灯集
int semid;
if((semid=semget(key,3,IPC_CREAT|IPC_EXCL|0664))<0)
{
//若文件存在切被创建直接赋予信号灯集id
if(errno==EEXIST)
{
semid=semget(key,3,IPC_CREAT|0664);
}
else
{
perror("semget error");
return -1;
}
}
else
{
//初始化信号灯
init_semnum_value(semid,0,1);
init_semnum_value(semid,1,0);
init_semnum_value(semid,2,0);
}
return semid;
}
//申请信号灯集的资源
int P(int semid,int semnum)
{
struct sembuf buf;
buf.sem_num=semnum;
buf.sem_op=-1; //表示申请资源
buf.sem_flg=0;
if(semop(semid,&buf,1)<0)
{
perror("P error");
return -1;
}
return 0;
}
//释放信号灯集的资源
int V(int semid,int semnum)
{
struct sembuf buf;
buf.sem_num=semnum;
buf.sem_op=1; //表示释放资源
buf.sem_flg=0;
if(semop(semid,&buf,1)<0)
{
perror("V error");
return -1;
}
return 0;
}
//删除信号灯集
int sem_del(int semid)
{
if(semctl(semid,0,IPC_RMID,0)<0)
{
perror("semctl error");
return -1;
}
return 0;