Reputation: 2664
I'm trying to design 5 producers and single consumer model. I have just learned how to design the model from Producer-consumer problem, Wikipedia. But I have hard time avoiding the dead lock. I don't understand why this code cause the dead lock.
Here is consumer. (Assume that single process executes this code. and all semaphores and shared memory are already initialized.)
int main()
{
Shared_Data = (shared_data*)Shared_Address; // this is a shared memory.
for(i = 0 ; i < 5; i++)
{
sprintf(debugbuf, "%ld, filled downsem, %dth loop\n", (long)getpid(), i);
write(STDOUT_FILENO, debugbuf, strlen(debugbuf));
sem_wait(filled); // try to access to the shared memory.
// if the shared memory is empty, consumer waits for it to be filled with pid and state.
read.isIdle = I_AM_IDLE;
read.WrittenByPid = Shared_Data->WrittenByPid;
sprintf(debugbuf, "%ld, empty upsem\n", (long)getpid());
write(STDOUT_FILENO, debugbuf, strlen(debugbuf));
sem_post(empty);
}
}
Here is producer. (Assume that five processes execute this code and all semaphores and shared memory are already initialized.)
int main()
{
sprintf(debugbuf, "%ld, empty downsem\n", (long)getpid());
write(STDOUT_FILENO, debugbuf, strlen(debugbuf));
// only one child process have access to here.
sem_wait(empty); // another child process doen't have access to here,
// untill parent process reads the shared memory.
sprintf(writebuf, "%s %ld process is forked.\n", Get_CurrentTime(date), (long)getpid());
write(STDOUT_FILENO, writebuf, strlen(writebuf));
Put_itsState_into_SharedMemory(getpid(), I_AM_IDLE, YES_Virgin);
sprintf(debugbuf, "%ld, filled upsem\n", (long)getpid());
write(STDOUT_FILENO, debugbuf, strlen(debugbuf));
sem_post(filled);
}
But I have the following result.
32685, filled downsem, 0th loop
32687, empty downsem
32687, filled upsem
32685, empty upsem
32685, filled downsem, 1th loop
32690, empty downsem
32689, empty downsem
32691, empty downsem
32688, empty downsem
[stuck in for-loop]
Any help would be awesome. Thank you.
Upvotes: 0
Views: 314
Reputation: 992
You should always check, what the return value of sem_wait
is.
If you are in the sem_wait
function and an interrupt comes in, then sem_wait
will return an error unequal to 0.
Then you need to check if an interrupt happened, with errno
.
Since you use fork
you can get the SIGCHLD
interrupt when one child process exits.
Upvotes: 2