Reputation: 957
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.
Upvotes: 0
Views: 725
Reputation: 27572
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.
Upvotes: 0
Reputation: 52407
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.
Upvotes: 1