Reputation: 85
The relevant snippets of code from the two programs are below. Basically, the consumer dequeues an integer from the shared buffer and the producer enqueues an integer from the command line. Without the call to sleep at the end of the loops, deadlock occurs. That is, both processes seem to wait for the semaphore. I don't understand how this could happen and would appreciate an explanation. Also, let me know if there is a proper alternative to my 'sleep to let the other process get a chance' solution. My gut tells me that there should be, which was the main reason I decided to post this question.
Consumer:
while (get_success == 0) {
// critical section
sem_wait(semaphore);
if (*top != *bottom || *empty == 0) { // not empty
printf("Stored Integer: %d\n", buffer[*bottom]);
*bottom = (*bottom + 1) % N;
if (*bottom == *top)
*empty = 1;
get_success = 1;
}
sem_post(semaphore);
// end critical section
if (get_success == 0)
sleep(1);
}
Producer:
while (ins_success == 0) {
// critical section
sem_wait(semaphore);
if (*top != *bottom || *empty == 1) { // not full
buffer[*top] = atoi(input);
*empty = 0;
*top = (*top + 1) % N;
ins_success = 1;
}
sem_post(semaphore);
// end critical section
if (ins_success == 0)
sleep(1);
}
Thanks!
Upvotes: 3
Views: 298
Reputation: 2101
What you haven't defined here is the "input" portion of your code. You have to be careful implementing multi-threaded design while utilizing I/O, and you should be particularly careful about the functions that you choose to call from within your critical sections.
In this portion of code, you call atoi() in both critical sections, so I would say that you should try peeling functionality out of your critical sections, until the issue is resolved, to give you a better idea of where your code is having issues.
Upvotes: 0
Reputation: 12043
Broadly, any answer to a question about process synchronization involving the use of sleep() is wrong. Never do that. At best you will produce performance bugs, at worst you will see priority inversion and deadlock issues.
The code you wrote (without the sleep!) looks to me like a reasonable attempt at mutual exclusion, and it should work. If you want the other process to wake up first, you need to use two semaphores: one to "hand the cookie" in each direction.
Upvotes: 0
Reputation: 97958
If you want to force the thread/process to yield the CPU you can use sched_yield. Sleep will force calling thread to wait even if it can continue, say, after 0.2 seconds. This is not for avoiding race conditions of course, you need semaphores for synchronization.
Upvotes: 2