for (i = 0; i < consumers; i++) {
Mutex_lock(&m);
while (num_full == max)
Cond_wait(empty_cv, &m);
do_fill(END_OF_STREAM);
do_eos();
Cond_signal(fill_cv);
Mutex_unlock(&m);
}
when the producer is finished, END_OF_STREAM will be written into buffer and one of consumers will wake up. However, I found that it is not as I expected. It seems like that one of consumers will be set to ready state and the for loop will release the lock but immediately acquire the lock again. because num_full equals max at this time so the for loop will sleep. then one of consumers will execute and finally wake up one thread between the other consumer and the for loop. however, it will choose the other consumer rather than the for loop. so END_OF_STREAM will not be written into buffer again and cause the whole program to crash. If I change the code to the following, then there is no problem.
for (i = 0; i < consumers; i++) {
sleep(1);
Mutex_lock(&m);
while (num_full == max)
Cond_wait(empty_cv, &m);
do_fill(END_OF_STREAM);
do_eos();
Cond_signal(fill_cv);
Mutex_unlock(&m);
}