#include<errno.h>
#include<stdlib.h>
#include<stdio.h>
#include<unistd.h>
//semaphore header file
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#define SEMPERM 0600
#define TRUE 1
#define FALSE 0
//
union semun{
int val;
struct semid_ds*buf;
unsigned short *array;
};
union semun arg;
//
struct databuf{
int in;
int out;
char buffer[5];
}
//system V header file
#include<sys/shm.h>
//#include<sys/ipc.h>
//#include<signal.h>
//#include<time.h>
#define N 5
//#define ERR ((struct databuf*)-1)
static int shmid,semid;
void initshm(struct databuf**p){
if((shmid=shmget(0x12,sizeof(struct databuf*),0600|IPC_CREAT|IPC_EXCL))==-1)
printf("shmget");
if((*p=(struct databuf*)shmat(shmid,0,0))==((struct databuf*)-1))
printf("shmid=%d",shmid);
}
//
int initsem(key_t semkey){
int status=0,semid;
if((semid=semget(semkey,3,SEMPERM|IPC_CREAT|IPC_EXCL))==-1)
{
if(errno==EEXIST) printf("semid eexist");
}
else
{
printf("semid=%d",semid);
arg.val=0;
if((status=semctl(semid,0,SETVAL,arg))==-1)
perror("semctl setval full error!");
arg.val=N;
if((status=semctl(semid,1,SETVAL,arg))==-1)
perror("semctl setval empty error!");
arg.val=1;
if((status=semctl(semid,2,SETVAL,arg))==-1)
perror("semctl setval mutex error!");
if(semid==-1||status==-1)
{
perror("initsem failed");
return(-1);
}
}
return(semid);
}
//
void remobj(){
if(shmctl(shmid,IPC_RMID,NULL)==-1) printf("shmctl");
if(semctl(semid,0,IPC_RMID,0)==-1)
{
if(errno==EIDRM)
perror("semctl remobj error EIDRM!");
}
}
//
int P(int semid,int sem_n){
// printf("sem_n=%d",sem_n);
struct sembuf p_buf;
p_buf.sem_num=sem_n;
p_buf.sem_op=-1;
p_buf.sem_flg=SEM_UNDO;
if(semop(semid,&p_buf,1)==-1)
{
perror("P(semid) failed");
exit(1);
}
return(0);
}
//
int V(int semid,int sem_n)
{
struct sembuf V_buf;
V_buf.sem_num=sem_n;
V_buf.sem_op=1;
V_buf.sem_flg=SEM_UNDO;
if(semop(semid,&V_buf,1)==-1)
{
perror("V(semid) failed");
exit(1);
}
return(0);
}
//
void producer(int semid,struct databuf*buf){
int in,i;
printf("\n pok\n");
/* char c;
c=getchar();
while(c!='q')
in=buf->in;
sleep(10);*/
for(i=0;i<8;i++)
{
printf("\n producer produce a product x\n");
P(semid,1);
P(semid,2);
buf->buffer[buf->in]='x';
printf("\n pid=%d put into buffer[%d]\n",getpid(),buf->in);
buf->in=(buf->in+1)%N;
V(semid,0);
v(semid,2);
//c=getchar();
}
}
//
void consumer(int semid,struct databuf*buf){
int out,i;
printf("\n cok\n");
/*char c;
out=buf->out;*/
for(i=0;i<8;i++)
{
P(semid,0);
P(semid,2);
buf->buffer[buf->out]='x';
printf("\n pid=%d get x out from buffer[%d]\n",getpid(),buf->out);
buf->out=(buf->out+1)%N;
V(semid,1);
V(semid,2);
}
}
main(){
key_t semkey=0x12;
int i,pid;
struct databuf*buf;
initahm(&buf);
semid=initsem(semkey);
printf("\n ok \n");
if((pid=fork())<0) printf("fork error!");
else if(pid==0)
{
fork();
producer(semid,buf);
}
else
{
fork();
consumer(semid,buf);
waitpid(pid,NULL,0);
remobj();
}
}