本文共 2697 字,大约阅读时间需要 8 分钟。
条件变量(Condtion Variable)是在多线程程序中用来实现“等待->唤醒”逻辑常用的方法。
举个实例场景:
一个进程p中有两个线程A和B。A运行到某处后,需要等到bool变量flag变为true后才能继续运行,而设置flag的值为true这个操作需要线程B来完成,这种情况我们如何来实现?
#includeint pthread_cond_init (pthread_cond_t *cond,const pthread_condattr_t *cond_attr) ;int pthread_cond_destroy (pthread_cond_t *cond);两者的返回值都是:若成功则返回0,否则返回错误号
/* 等待条件变为真 */int pthread_cond_wait (pthread_cond_t *cond,pthread_mutex_t *mutex);/* 限时等待条件为真 */int pthread_cond_timedwait (pthread_cond_t *cond,pthread_mutex_t *mutex,const struct timespec *abstime);传递给pthread_cond_wait的互斥量对条件进行保护。调用者把锁住的互斥量传给函数,函数然后把调用线程放到等待条件的线程列表中,对互斥量解锁。pthread_cond_wait返回时,互斥量再次被锁住。
#include<pthread.h>
int pthread_cond_signal(pthread_cond_t *cond);
in pthread_cond_broadcast(pthread_cond_t *cond);
两个函数的返回值:若成功,返回0;否则,返回错误编号
以下代码摘自unix环境高级编程
#includestruct msg { struct msg *m_next; /* ... more stuff here ... */};struct msg *workq;pthread_cond_t qready = PTHREAD_COND_INITIALIZER;pthread_mutex_t qlock = PTHREAD_MUTEX_INITIALIZER;voidprocess_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); /* now process the message mp */ }}voidenqueue_msg(struct msg *mp){ pthread_mutex_lock(&qlock); mp->m_next = workq; workq = mp; pthread_mutex_unlock(&qlock); pthread_cond_signal(&qready);}
为什么使用while而不是if
while (...) pthread_cond_wait(&qready, &qlock);
1.假设仓库为空,有2个消费者在等待商品,设为C1和C2
2.假设生产者只生产了1件商品,然后调用pthread_cond_broadcast,则C1和C2都会得到通知
3.假设C1比C2先得到通知,然后加锁把商品消费了,并且解锁,这时C2就能拿到锁,但是此时商品已经没有了,如果此时C2不做检测,则会出现数据同步问题
转载地址:http://kiumi.baihongyu.com/