使用信号灯集实现,三个进程分别输出ABCABCABCABCABC
zuo.c
#include <head.h>
#include "sem.h"
#define SIZE 4096
int main(int argc, const char *argv[])
{
int semid=init_sem();
if(semid==-1)
{
printf("信号灯集创建失败\n");
return -1;
}
pid_t pid1=fork();
if(pid1>0)
{
pid_t pid2=fork();
if(pid2>0)
{
int num=5;
while(num--)
{
sleep(1);
P(semid,0);
printf("A");
fflush(stdout);
V(semid,1);
}
}
else if(pid2==0)
{
int num=5;
while(num--)
{
sleep(1);
P(semid,1);
printf("B");
fflush(stdout);
V(semid,2);
}
exit(0);
}
else
{
perror("fork pid2");
return -1;
}
}
else if(pid1==0)
{
int num=5;
while(num--)
{
sleep(1);
P(semid,2);
printf("C");
fflush(stdout);
V(semid,0);
}
exit(0);
}
else
{
perror("fork");
return -1;
}
return 0;
}
sem.c
#include <head.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_semnum_value(int semid,int semnum,int value)
{
union semun s;
s.val=value;
if(semctl(semid,semnum,SETVAL,s)==-1)
{
perror("semctl");
return -1;
}
return 0;
}
int init_sem()
{
key_t key=ftok("./",'q');
if(key==-1)
{
perror("ftok");
return -1;
}
int semid=semget(key,3,IPC_CREAT|IPC_EXCL|0664);
if(semid==-1)
{
if(errno==EEXIST)
{
semid=semget(key,3,IPC_CREAT|0664);
}else
{
perror("semget");
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)==-1)
{
perror("P");
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)==-1)
{
perror("V");
return -1;
}
return 0;
}
int sem_del(int semid)
{
if(semctl(semid,0,IPC_RMID,0)==-1)
{
perror("semctl");
return -1;
}
return 0;
}
sem.h
#ifndef __SEM_H__
#define __SEM_H__
int init_sem();
int P(int semid,int semnum);
int V(int semid,int semnum);
int sem_del(int semid);
#endif