预备知识:
pthread_cond_t
这是Linux库中的一个变量类型,表示多线程的条件变量,用于控制线程等待和就绪的条件。
pthread_cond_init()
muduo库用次函数来初始化条件变量。
它的原型为:
extern int pthread_cond_init __P ((pthread_cond_t *__cond,__const pthread_condattr_t *__cond_attr));
其中cond是一个指向结构pthread_cond_t的指针,
cond_attr是一个指向结构pthread_condattr_t的指针。
结构pthread_condattr_t是条件变量的属性结构,和互斥锁一样我们可以用它来设置条件变量是进程内可用还是进程间可用,默认值是PTHREAD_ PROCESS_PRIVATE,即此条件变量被同一进程内的各个线程使用;如果选择为PTHREAD_PROCESS_SHARED则为多个进程间各线程公用。muduo库中使用的是默认值,注意初始化条件变量只有未被使用时才能重新初始化或被释放。
返回值:函数成功返回0;任何其他返回值都表示错误。
释放一个条件变量的函数为pthread_cond_ destroy(pthread_cond_t *cond)。
pthread_cond_destroy()
注销一个条件变量需要调用pthread_cond_destroy(),只有在没有线程在该条件变量上等待的时候才能注销这个条件变量,否则返回EBUSY。因为Linux实现的条件变量没有分配什么资源,所以注销动作只包括检查是否有等待线程。API定义如下:
int pthread_cond_destroy(pthread_cond_t *cond)
new开辟的pthread_cond_t记得在调用pthread_cond_destroy()后调用delete或者free销毁掉。
int pthread_cond_wait(pthread_cond_t * cond, pthread_mutex_t * mutex);
pthread_cond_signal() //激活一个等待程序
pthread_cond_broadcast() //激活所有的等待程序
使用流程
等待线程:
pthread_mutex_lock(&mutex);
if(条件不满足)
pthread_cond_wait(&cond, &mutex);
//处理共享资源
pthread_mutex_unlock(&mutex);
激活线程:
pthread_mutex_lock(&mutex);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
pthread_cond_wait(&cond, &mutex);一定要与一个互斥量相互使用。进入pthread_cond_wait()函数后,先上锁,再将此线程挂到等待的队列中,然后解锁。直到满足条件,此线程会被唤醒,唤醒后先上锁,再退出pthread_cond_wait()函数。
UML:
解释:
为了让Condition中的wait()函数与pthread_cond_wait()函数能够达到同样的效果,源码中会有一些特殊的写法。
void wait()
{
MutexLock::UnassignGuard ug(mutex_);
//进入wait时,先解锁(构造UnassignGuard类),退出wait时(析构UnassignGuard类),上锁。
//这里所说的上锁,是对MutexLock类形式上的上锁,通过改变holder_的值来实现形式上的上锁
MCHECK(pthread_cond_wait(&pcond_, mutex_.getPthreadMutex()));
//pthread_cond_wait会对pthread_mutex_t进行解锁和上锁
}