I was going through this and this link. Basically, they are discussing why classical single threaded producer consumer design (with signal
and wait
does not work for multi-producer scenario). I have one doubt which has been bugging me -
Argument made by author
Consider reference code
char queue[MAX]; //global
int head = 0, tail = 0; //global
struct cv not_full, not_empty;
struct lock qlock;
void produce(char data) {
acquire(&qlock);
if ((head + 1) % MAX == tail) {
wait(¬_full, &qlock); //line 1
}
queue[head] = data; //line 2
head = (head + 1) % MAX;
notify(¬_full);
release(&qlock);
}
char consume(void) {
acquire(&qlock);
if (tail == head) {
wait(¬_empty, &qlock);
}
e = queue[tail];
tail = (tail + 1) % MAX;
notify(¬_empty);
release(&qlock);
return e;
}
In the above code, in case of two producer, line 1
will be woken up
in both the producer thread by single consumer (when queue is not full). So both producer can add to the queue leading to queue overflow.
My doubt
a. We are protecting the queue with mutex lock. So even if wait
is woken up on multiple producer thread, only one producer would still have mutex lock - so logically there would be only one producer 'owning' rights to add to queue. Because when we come out of wait
we would have mutex to be acquired.
Cavet
I use POSIX mutex,cond var as reference. However, I do not see article written with POSIX as reference standard.
Question
Is my understanding of wait
specifically pthread_cond_wait
correct? And with multiple producers, the integrity of the code is still maintained.