条件变量
使用环境
我对Condition的理解是这样的调用signal和broadcast的线程和调用wait的线程不是无差别的,他们有差别,有先后关系,比如说没有wait的线程,signal是无用的。与mutex对比就会发现使用mutex的线程之间是没有差别的,他们谁离了谁都是一样的,他们之间仅仅是争资源而已。
结论是:使用mutex的线程之间是竞争关系,而使用condition的线程之间是合作关系。
数据结构
pthread_cond_t
pthread_condattr_t
关键操作
int pthread_cond_init(pthread_cond_t *restrict cond,const pthread_condattr_t *restrict attr);
int pthread_cond_destroy(pthread_cond_t *cond);
int pthread_cond_wait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex);
int pthread_cond_timedwait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex,const struct timespec *restrict tsptr);
之所以给wait传入一个mutex,是因为调用wait之前先要lock mutex,wait进行的操作是把condition挂到等待列表中,再unlock mutex。等到wait退出的时候再lock
int pthread_cond_signal(pthread_cond_t *cond);
int pthread_cond_broadcast(pthread_cond_t *cond);
高级操作
int pthread_condattr_init(pthread_condattr_t * attr);
int pthread_condattr_destroy(pthread_condattr_t* attr);
int pthread_condattr_getpshared(const pthread_condattr_t *restrct attr, int *restrict pshared);
int pthread_condattr_setpshared(pthread_condattr_t *attr, int pshared);
int pthread_condattr_getclock(pthread_condattr_t *restrict attr,clockid_t *restrict clock_id);
int pthread_condattr_setclock(pthread_condattr_t *attr,clockid_t clock_id);
getclock和setclock都是在调用timedwait时才有效果,clock_id的选值有:
CLOCK_REALTIME
CLOCK_MONOTONIC
CLOCK_PROCESS_CPUTIME_ID
CLOCK_THREAD_CPUTIME_ID
测试例子
#include<pthread.h>
#include<stdio.h>
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static int flag = 0;
void *
test1 (void *arg)
{
while (1)
{
pthread_mutex_lock (&mutex);
while (flag != 1)
pthread_cond_wait (&cond, &mutex);
printf ("T1\n");
flag = 2;
pthread_mutex_unlock (&mutex);
pthread_cond_broadcast (&cond);
}
}
void *
test2 (void *arg)
{
while (1)
{
pthread_mutex_lock (&mutex);
while (flag != 2)
pthread_cond_wait (&cond, &mutex);
printf ("T2\n");
flag = 3;
pthread_mutex_unlock (&mutex);
pthread_cond_broadcast (&cond);
}
}
void *
test3 (void *arg)
{
while (1)
{
pthread_mutex_lock (&mutex);
while (flag != 3)
pthread_cond_wait (&cond, &mutex);
printf ("T3\n");
flag = 1;
pthread_mutex_unlock (&mutex);
pthread_cond_broadcast (&cond);
}
}
int
main ()
{
pthread_t p1, p2, p3;
pthread_create (&p1, NULL, test1, 0);
pthread_create (&p2, NULL, test2, 0);
pthread_create (&p3, NULL, test3, 0);
pthread_mutex_lock (&mutex);
flag = 1;
pthread_mutex_unlock (&mutex);
pthread_cond_signal (&cond);
pause ();
return 0;
}