7
votes

I'm a little bit confused on how to initialize and implement a pthread mutex and condition variable. The goal of the program is to have producers place a set number of ints in a queue and consumers take the ints out of the queue. I must also be able to define the number of producer and consumer threads that are created. In the starter code, I am give these:

// Locks & Condition Variables
pthread_mutex_t lock; // Lock shared resources among theads
pthread_cond_t full;  // Condition indicating queue is full
pthread_cond_t empty; // Condition indicating queue is empty

as shared resources. In the //TODO comment in the main method, one of the steps says to initialize the lock and condition variables. I have a very weak understanding of pthread mutex's and conditions, so would I say:

lock = PTHREAD_MUTEX_INIT;
full = PTHREAD_MUTEX_INIT;
empty = PTHREAD_MUTEX_INIT;

In the consumer and producer methods, would i just call the lock by saying:

pthread_mutex_lock(&lock);

and

pthread_cond_wait(&full, &lock);

?

My code is pretty buggy right now, so I want to at least make sure that I'm using the mutex's and conditions correctly before debugging further. Thanks in advance!

1
What is your question exactly?this
The mutex I'm pretty sure you have a handle on, but the vernacular in comments for those condition vars looks like a problem. Condition variables don't "indicate" anything. They're a signaling mechanism. That mechanism, when properly used in conjunction with a mutex, signals changes in the state of external predicate data that you own.WhozCraig
Oh, and don't initialize condition variable with PHREAD_MUTEX_INIT. That's clearly wrong. Use PTHREAD_COND_INITIALIZER.WhozCraig
My question is whether or not I am implementing those correctly. My code is buggy and i'm trying to see if I at least correctly initialized and called these.user3591210
And thanks WhozCraig, i'm using them as a signaling mechanism. I just think that the professor incorrectly worded the comment.user3591210

1 Answers

18
votes

If you want to use the PTHREAD_XXX_INITIALIZER macros you should use them in the variable declaration. Also use PTHREAD_COND_INITIALIZER for condition variables:

// Locks & Condition Variables
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; // Lock shared resources among theads
pthread_cond_t full  = PTHREAD_COND_INITIALIZER;  // Condition indicating queue is full
pthread_cond_t empty = PTHREAD_COND_INITIALIZER; // Condition indicating queue is empty

Don't use those macros to initialize the mutex or condition variable later. If you need to do it later (for example if the object is dynamically allocated), use the appropriate init function:

pthread_mutex_init( &lock, NULL);
pthread_cond_init( &full, NULL);
pthread_cond_init( &empty, NULL);

To check a condition variable you must use a loop in order to avoid spurious unblocks and you must lock the mutex when:

  • checking the condition
  • changing the state that indicates the current condition
  • calling pthread_cond_wait()

So whatever is waiting for an is-empty condition might look like:

pthread_mutex_lock(&lock);
while (!isEmpty) {
    pthread_cond_wait(&empty, &lock);
}

// isEmpty is non-zero and the lock is held

Whatever is signalling that something is-empty might look like:

pthread_mutex_lock(&lock);

// ...
// we have emptied the queue while holding the lock

isEmpty = 1;
pthread_mutex_unlock(&lock);
pthread_cond_signal(&empty);