Reputation: 1530
Below is the code of an example consumer/producer model:
int buffer[MAX];
int fill_ptr = 0;
int use_ptr = 0;
int count = 3;
void put(int value) {
buffer[fill_ptr] = value;
fill_ptr = (fill_ptr + 1) % MAX;
count++;
}
int get() {
int tmp = buffer[use_ptr];
use_ptr = (use_ptr + 1) % MAX;
count--;
return tmp;
}
cond_t empty, fill;
mutex_t mutex;
void *producer(void *arg) {
int i;
for (i = 0; i < loops; i++) {
pthread_mutex_lock(&mutex); // p1
while (count == MAX) // p2
pthread_cond_wait(&empty, &mutex); // p3
put(i);// p4
pthread_cond_signal(&fill); // p5
pthread_mutex_unlock(&mutex); // p6
}
}
void* consumer(void *arg) {
int i;
for (i = 0; i < loops; i++) {
pthread_mutex_lock(&mutex); // c1
while (count == 0) // c2
pthread_cond_wait(&fill, &mutex); // c3
int tmp = get(); // c4
pthread_cond_signal(&empty); // c5
pthread_mutex_unlock(&mutex); // c6
printf("%d\n", tmp);
}
}
However, I think there is a problem in here. Assume MAX=3, and initially the buffer is full (count = 3), then the consumer can execute a get()
and signal to the producer. After the producer receives a signal, it wakes up and begins to execute put()
in buffer[0] with the mutex held.
Assume the producer just got stuck in put()
; then the consumer cannot continue either (because the mutex is held by producer) even though there are 2 resources left.
Is my understanding correct? If so, that's unfair because there are 2 resources left which can be consumed.
Upvotes: 0
Views: 139
Reputation: 44310
Is my understanding correct?
Both yes and no.
Yes, it is correct that the consumer
will be stuck if the producer
calls put
and put
gets stuck (e.g. by entering a endless loop).
However, you can't assume that there are 2 resources left
. The pthread_cond_signal
does not promise the producer
executes before the consumer
have read all 3 three elements. All you can know is that the consumer
read at least one element but maybe it read 2 or even 3 before the producer executes.
If so, that's unfair ....
No, it is not unfair. It is exactly what a mutex is for, i.e. making sure that only one thread has access to the shared resource.
Therefore it is important to make sure that a thread holding a mutex will not get stuck! That is your responsibility as a programmer.
Note: In your case there is nothing inside put that can cause the thread to be stuck.
Upvotes: 1
Reputation: 182779
Assume the producer just got stuck in put(); then the consumer cannot continue either (because the mutex is held by producer) even though there are 2 resources left.
You must never do something that can get stuck while you hold the mutex, and your code does not.
Upvotes: 1