0

I'm attempting to create the producer-consumer problem in C using semaphores and shared memory. I've got the semaphores and shared memory working but I'm having trouble determining how to run the individual consumers and producers.

This IS homework, and the requirements state the producer and consumer must be single threaded processes. I've contacted the prof and he recommended using fork(). I assume this means I can't use pthread().

Currently, I have separate applications for the producer and consumer (ie they each have their own main()). I need to be able to run as many sets of producers and consumers as the user specifies, and to terminate the application after a set amount of time.

Originally I tried this

int Ppid = fork();
if(Ppid == 0){
    execv("pathtoproducer", NULL);
}
int Cpid = fork();
if(Cpid == 0){
    execv("pathtoconsumer", NULL);
}
//close semaphores and detach shared memory

Of course this leads to issues as the application will close the semaphore before running the forked process.

So I'm thinking of doing something like this:

 int pid = fork();
 if(pid == 0){
     execv("pathtoproducer", NULL);
     execv("pathtoconsumer", NULL);
 }
 else{
    //wait for timer to run out
 }
 //detach shared memory and close semaphore

But of course since I'm using execv the consumer will never run. Is there something I can use to get both the producer and consumer to run (keep in mind I'll need to have n amount of them, I'm just trying with a single set in this example).

Thanks.

user1287523
  • 967
  • 3
  • 14
  • 31

2 Answers2

1

Well, you can always do a nested fork.

 int pid = fork();
 if (pid == 0){
     int pid2 = fork();
     if (pid2 == 0)
         execv("pathtoproducer", NULL);
     else
         execv("pathtoconsumer", NULL);
 } else {

Btw. there are better ways to wait for your children than a timer.

ypnos
  • 50,202
  • 14
  • 95
  • 141
  • Just for testing I have my producer and consumer editing to shared memory and semaphores rather than actually being stuck in a while true. I can't get this code to work. It creates the producer, then runs the rest of the parent, then reprints my console line (user@user-whatever), then runs the producer. I just want it to create a bunch of pairs of consumers and producers and end after an allotted time, then execute the remaining code in the parent. – user1287523 Oct 27 '12 at 22:09
0

Maybe I am missing part of your requirements but you seem to be making this harder than it is.

for (i=0...numConsumers)
    fork consumers; //they can't do anything without something to consume

for (i=0...numProducers)
    fork producers;

select(null, null, null, null, timetowait);

for (i=0...numProducers + numConsumers)
    kill(childPid, sigusr1);
    wait();

//whatever remain todo in parent...

You'll need a simple signal handler in the producer/consumer programs that gets caught and the program(s) then proceed to shut themselves down in an orderly fashion. If you don't want to use signals you can use pipes or whatever...including a simple shared memory switch since you already have that working anyway.

Duck
  • 26,924
  • 5
  • 64
  • 92