问题
I am trying to create a program where there is one master thread and multiple worker threads. Worker threads will register themselves in a shared queue and will wait for a signal from master thread to move on. Master thread will check front of queue and will signal that thread by using it's own specific condition variable, to move on. Here is the pseudo-code that i have right now,
struct condition{
pthread_cond_t cond_var;
pthread_mutex_t lock;
};
queue<condition> queue;
pthread_mutex_t lock;
pthread_cond_t cond;
void *Master()
{
while(/* some condition*/)
{
pthread_mutex_lock( &lock );
condition next_obj;
if(!queue.empty())
{
next_obj = queue.front();
landing_queue.pop();
pthread_cond_signal( &next_obj.cond_var );
}
pthread_cond_broadcast( &cond );
pthread_mutex_unlock( &lock );
sleep(2 sec);
}
pthread_exit(NULL);
}
void *Woker()
{
condition new_obj;
pthread_mutex_init(&new_obj.lock, NULL);
pthread_cond_init(&new_obj.cond_var, NULL);
pthread_mutex_lock( &new_obj.lock );
pthread_mutex_lock( &lock );
pthread_cond_wait( &cond, &lock );
queue.push(new_obj);
pthread_cond_broadcast( &cond );
pthread_mutex_unlock( &lock );
pthread_cond_wait( &new_obj.cond_var, &new_obj.lock );
pthread_exit(NULL);
}
In this code struct condition holds condition variable and lock for a specific thread, i am locking worker thread by it's own cond_var and lock stored in struct condition and then unlock it in master thread by using same stored lock and cond_var in queue. Now everything is working fine but master thread's signal to worker is not working, worker keeps waiting even after master sends the signal. Please tell me that if there is something wrong with the flow or if there is another way to achieve this.
回答1:
A bare condition variable and mutex isn't sufficient: a condition variable needs to be paired with a condition over some shared state (hence the name). A simple example would be to augment your condition
struct with a flag variable:
struct condition {
pthread_cond_t cond_var;
pthread_mutex_t lock;
int flag;
};
Where the flag
variable is protected by the lock
mutex.
The worker thread could then use the condition variable to wait for the flag
to be set:
void *Woker()
{
condition new_obj;
pthread_mutex_init(&new_obj.lock, NULL);
pthread_cond_init(&new_obj.cond_var, NULL);
new_obj.flag = 0;
/* publish new_obj to queue */
pthread_mutex_lock(&lock);
queue.push(new_obj);
pthread_mutex_unlock(&lock);
/* Wait for flag to be set */
pthread_mutex_lock(&new_obj.lock);
while (!new_obj.flag)
pthread_cond_wait(&new_obj.cond_var, &new_obj.lock);
pthread_mutex_unlock(&new_obj.lock);
pthread_exit(NULL);
}
...and your master thread would set the flag and signal the condition:
pthread_mutex_lock(&next_obj.lock);
next_obj.flag = 1;
pthread_cond_signal(&next_obj.cond_var);
pthread_mutex_unlock(&next_obj.lock);
来源:https://stackoverflow.com/questions/37019144/control-each-thread-by-its-own-condition-variable-c