Reputation: 456
I have a general question that may be easy to answer, but it might not be. I'm not sure. In my code I have four threads running, all working to work their way through a list, each popping a piece of it each time they run. Below is the code for each thread, where they wait for the mutex to unlock, lock it themselves, do their thing, and then relock the mutex.
My question is this: Is there a way to pass the lock to a specific thread?\
For example: If I had four threads running this code (t1, t2, t3, and t4) and t1 just finished, is there a way that I can guarantee that t1 will pass the lock to t2, and t2 will pass the lock to t3, etc?
void *consumer(void *ptr){
int i;
// Print the thread ID
printf("Consumer TID %lu\n", (unsigned long)gettid());
// While the list isn't empty
while (1){
// Wait for the mutex
pthread_mutex_lock(&mutex);
// When you get it...
// If the list is empty
if (the_list.empty()){
// Unlock the mutex
pthread_mutex_unlock(&mutex);
break;
}
// Otherwise remove an element from the list
the_list.pop_front();
// And unlock the mutex
pthread_mutex_unlock(&mutex);
}
return NULL;
}
Thank you!
UPDATE - RANDOM THOUGHT: I just had a thought. Could there be four different functions that each took in a specific mutex only released by the previous function?
Upvotes: 0
Views: 1086
Reputation: 12514
Your problem with the consumer is that it needs to stay ready even if the list gets empty.
I say this because it might be the case that the consumer is up-and-ready before the first producer comes. In that situation the consumer sees an empty list and exits, thus no produced elements will be consumed.
So I would suggest rather
pthread_mutex_lock(&mutex);
while(the_list.empty())
pthread_cond_wait(&produced, &mutex);
pthread_mutex_unlock(&mutex);
And the producer(s) will signal you the signal pthread_cond_signal(&produced)
.
I think this also yields an answer to your question: you don't "pass the lock", but signal (and wait for the signal -- if you are interested in the "passing of the lock" you could do it with 3-4 different signals).
As for the locks: the locks are per-data not per-thread. So the lock is usually stored together with the data.
struct threadsafe_data_t {
data_t data;
pthread_mutex_t mutex;
pthread_cond_t modified; // or produced or whatever
};
Upvotes: 3