bareta@ihuxv.ATT.COM (Benyukhis) (04/19/88)
Good morning usenetters, Can anyone outthere help me code the producer/consumer problem in "C". The prolog is as follows: the producer has to produce a char and deposit it in the shareable buffer for consumer to pick it up from. Both processes must use binary semaphores as a means of synchronization. It looks trivial, but for someone that has never written anything for more than one process .... In other words, if anyone has any helpfull hints for me, I would really appreciate it. Thanks in advance, Ed.
les@chinet.UUCP (Leslie Mikesell) (04/20/88)
In article <2592@ihuxv.ATT.COM> bareta@ihuxv.ATT.COM (Benyukhis) writes: > >Can anyone outthere help me code the producer/consumer problem >in "C". The prolog is as follows: the producer has to produce >a char and deposit it in the shareable buffer for consumer to pick it up >from. Both processes must use binary semaphores as a means of >synchronization. This sounds like you could use a pipe and avoid the need for any semaphores. If this is a simple 1 to 1 arrangement, you can just write producer to output to stdout, and consumer to read from stdin. Then let the shell set up the pipe with "producer | consumer". Or, one program can fork off a child process with a pipe connected (popen() will do it all for you). If you have multiple producers/one consumer or they cannot have the same parent process, you can use a FIFO or named pipe (see mknod(1) and mknod(2)). Les Mikesell
mechjgh@tness7.UUCP (Greg Hackney ) (04/21/88)
In article <2592@ihuxv.ATT.COM> bareta@ihuxv.ATT.COM (Benyukhis) writes: >the producer has to produce >a char and deposit it in the shareable buffer for consumer to pick it up >from. Both processes must use binary semaphores as a means of >synchronization. It looks trivial, but for someone that has never >written anything for more than one process I'm not sure if this is what you want, but here are 4 simple demo programs for writing lines of IPC "messages", open.c, send.c, receive.c, and close.c. open 777 # opens a message queue ipcs # show the queue status send 777 text # send some text ipcs # show the queue status send 777 text1 # send some more text ipcs # show the queue status rec 777 # read some text rec 777 # read some text close 777 # close the queue ipcs # show the queue status -- Greg {ihnp4 | bellcore}!tness1!mechjgh #!/bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #!/bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # close.c # open.c # rec.c # send.c # This archive created: Wed Apr 20 18:19:26 1988 export PATH; PATH=/bin:$PATH if test -f 'close.c' then echo shar: over-writing existing file "'close.c'" fi cat << \SHAR_EOF > 'close.c' /* close.c */ #include <stdio.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> main(argc,argv) int argc; char *argv[]; { int qid; int syserr(); /*see if the queue is open, and get queue ID number */ if((qid=msgget(atoi(argv[1]),0666 & ~IPC_CREAT))== -1) syserr("Queue was not open!\n"); /*close the queue*/ if((msgctl(qid,IPC_RMID,NULL)) == -1) syserr("Can't close the queue\n"); printf("Queue closed successfully\n"); exit(0); } syserr(msg) char *msg; { extern int errno, sys_nerr; extern char *sys_errlist[]; fprintf(stderr,"ERROR: %s (%d", msg, errno); if(errno > 0 && errno < sys_nerr) fprintf(stderr, ";%s)\n", sys_errlist[errno]); else fprintf(stderr,")\n"); exit(1); } SHAR_EOF if test -f 'open.c' then echo shar: over-writing existing file "'open.c'" fi cat << \SHAR_EOF > 'open.c' /*open.c*/ #include <stdio.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #define MAXOPEN 20 main(argc,argv) int argc; char *argv[]; { int id; int syserr(); if((id=openqueue(atoi(argv[1]))) == -1) syserr("Can't open a queue\n"); printf("Queue ID is %ld\n",id); exit(0); } static int openqueue(key) /* return queue ID; create if necessary */ long key; { static struct{ long key; int qid; }queues[MAXOPEN]; int i, avail, qid; extern int errno; avail = -1; for(i=0; i < MAXOPEN; i++){ if(queues[i].key == key) return(queues[i].qid); if(queues[i].key == 0 && avail == -1) avail=i; } if(avail == -1){ errno=0; return(-1); } if((qid=msgget(key,0666 | IPC_CREAT))== -1) return(-1); queues[avail].key = key; queues[avail].qid = qid; return(qid); } syserr(msg) char *msg; { extern int errno, sys_nerr; extern char *sys_errlist[]; fprintf(stderr,"ERROR: %s (%d", msg, errno); if(errno > 0 && errno < sys_nerr) fprintf(stderr, ";%s)\n", sys_errlist[errno]); else fprintf(stderr,")\n"); exit(1); } SHAR_EOF if test -f 'rec.c' then echo shar: over-writing existing file "'rec.c'" fi cat << \SHAR_EOF > 'rec.c' /*receive.c*/ #include <stdio.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #define MSGSIZE 100 struct foo { long mtype; /* message type */ char mtext[100]; /* message text */ }; struct foo buf; main(argc,argv) int argc; char *argv[]; { int qid; int ret; int syserr(); /* check to see if the message queue has been opened, and get the queue ID number */ if((qid=msgget(atoi(argv[1]),0666 & ~IPC_CREAT))== -1) syserr("Queue was not open!\n"); printf("Got a qid of %d\n",qid); /*set the message type*/ buf.mtype=1; /*get the message from queue */ if((msgrcv(qid,&buf,sizeof(buf) - sizeof(buf.mtype),0L,0)) == -1){ printf("Return was %d\n",ret); syserr("Can't read the queue\n"); } printf("Return was %d\n",ret); printf("%s\n",buf.mtext); exit(0); } syserr(msg) char *msg; { extern int errno, sys_nerr; extern char *sys_errlist[]; fprintf(stderr,"ERROR: %s (%d", msg, errno); if(errno > 0 && errno < sys_nerr) fprintf(stderr, ";%s)\n", sys_errlist[errno]); else fprintf(stderr,")\n"); exit(1); } SHAR_EOF if test -f 'send.c' then echo shar: over-writing existing file "'send.c'" fi cat << \SHAR_EOF > 'send.c' /*send.c*/ #include <stdio.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #define MSGSIZE 100 struct foo { long mtype; /* message type */ char mtext[100]; /* message text */ }; struct foo BUF; main(argc,argv) int argc; char *argv[]; { int qid; int ret; int syserr(); /*see if the queue is open, and get the queue ID */ if((qid=msgget(atoi(argv[1]),0666 & ~IPC_CREAT))== -1) syserr("Queue was not open!\n"); /*set the message type*/ BUF.mtype = 1; sprintf(BUF.mtext,"%s\0",argv[2]); /*put the message in queue*/ if((ret=msgsnd(qid,&BUF,sizeof(BUF) - sizeof(BUF.mtype),0)) == -1) syserr("Can't send the queue\n"); printf("Return was %d\n",ret); printf("Message queued successfully\n"); exit(0); } syserr(msg) char *msg; { extern int errno, sys_nerr; extern char *sys_errlist[]; fprintf(stderr,"ERROR: %s (%d", msg, errno); if(errno > 0 && errno < sys_nerr) fprintf(stderr, ";%s)\n", sys_errlist[errno]); else fprintf(stderr,")\n"); exit(1); } SHAR_EOF # End of shell archive exit 0