1.条件变量(pthread_cond_t)是 线程可用的一种 同步机制;
2.条件变量 与 互斥量(pthread_mutex_t) 一起使用时,允许线程 以 无竞争的方式等待特定的条件发生;
3.条件本身是由互斥量保护,线程在改变条件状态之前必须首先锁住互斥量;
#include <pthread.h>
//静态初始化
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
//动态初始化
int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t
*cond_attr);
//至少唤醒一个等待该条件的线程
int pthread_cond_signal(pthread_cond_t *cond);
//唤醒等待该条件的所有线程
int pthread_cond_broadcast(pthread_cond_t *cond);
//调用者把锁住的互斥量传给函数,函数自动把调用线程放到等待条件的线程列表上,对互斥量解锁,
//进入睡眠状态
//pthread_cond_wait返回时,互斥量再次被锁住
//流程:互斥量加锁 --》 pthread_cond_wait()对互斥量解锁,等待信号
// --》 收到 pthread_cond_signal发送的 信号 --》pthread_cond_wait重新获取互斥量并返回,
//同时对互斥量进行 加锁
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
//与pthread_cond_wait类似,多了个超时abstime
int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t
*mutex, const struct timespec *abstime);
//对条件变量进行反初始化,
int pthread_cond_destroy(pthread_cond_t *cond);
示例:结合使用条件变量和互斥量 对线程进行同步
#include <pthread.h>
struct msg{
struct msg *m_next;
/..../
};
struct msg *workq;
pthread_cond_t qready = PTHREAD_COND_INITIALIZER; //静态初始化
pthread_mutex_t qlock = PTHREAD_MUTEX_INITIALIZER;
void process_msg(void)
{
struct msg *mp;
for(;;)
{
pthread_mutex_lock(&qlock);
while(workq == NULL)
pthread_cond_wait(&qready, &qlock);
mp = workq;
workq = mp->m_next;
pthread_mutex_unlock(&qlock);
/*process ...*/
}
}
void enqueue_msg(struct msg* mp)
{
pthread_mutex_lock(&qlock);
mp->m_next = workq;
workq = mp;
//这里可以先 解锁互斥量,也可以先发送条件变量的信号再解锁互斥量,后者可以避免 pthread_cond_wait
//接收到信号返回后 对互斥量加锁时 可能还需要跟其他线程 竞争 该互斥量的使用的问题
pthread_cond_signal(&qready);
pthread_mutex_unlock(&qlock);
//pthread_mutex_unlock(&qlock);
//pthread_cond_signal(&qready);
}
摘抄自<<UNIX 环境高级编程>> 11.6.6 条件变量(332页) 。