HuangJie
HuangJie

Reputation: 1530

Consumer/producer program got stuck

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

Answers (2)

4386427
4386427

Reputation: 44310

Is my understanding correct?

Both yes and no.

Yes, it is correct that the consumerwill 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_signaldoes 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

David Schwartz
David Schwartz

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

Related Questions