Condition Variable(简称Condition)是Posix定义的一种同步机制 - Thread为了某些数据的特定状态,而阻塞执行,等待其它Thread的通知。使用时有个限制 - Condition Variable必须与Mutex关联使用。怎么感觉有点像关联到信号量的Event?
int pthread_cond_init(pthread_cond_t *pCond, pthread_condattr_t *pAttr);
int pthread_cond_destroy(pthread_cond_t *pCond);
使用pthread_cond_init(),根据属性pAttr来初始化pCond。如果pAttr为NULL,则使用默认属性。不同版本的属性定义略有区别
/* Vx6 Kernel */
typedef struct
{
int condAttrStatus;
}pthread_condattr_t;
/* Vx6 RTP */
typedef struct
{
int condAttrStatus;
clockid_t _CondAttrClockId;
}pthread_condattr_t;
/* Vx7 */
typedef struct
{
int condAttrStatus;
int condAttrPshared;
unsigned int condAttrClockId;
}pthread_condattr_t;
与属性相关的API有这些
/*
* condAttrStatus
* PTHREAD_INITIALIZED_OBJ - 默认值
* PTHREAD_DESTROYED_OBJ
*/
int pthread_condattr_init(pthread_condattr_t *pAttr);
int pthread_condattr_destroy(pthread_condattr_t *pAttr);
/*
* condAttrClockId
* CLOCK_REALTIME - 默认值
* CLOCK_MONOTONIC
*/
int pthread_condattr_getclock(pthread_condattr_t *pAttr, clockid_t *pClockId);
int pthread_condattr_setclock (pthread_condattr_t *pAttr, clockid_t clockId);
/*
* condAttrPshared
* PTHREAD_PROCESS_PRIVATE - 默认值
* PTHREAD_PROCESS_SHARED
*/
int pthread_condattr_getpshared (const pthread_condattr_t *pAttr, int *pShared);
int pthread_condattr_setpshared (pthread_condattr_t *pAttr, int shared);
操作Condition Variable的API有
/*
* 这个函数释放pMutex,然后进入阻塞,等待其它Thread以Signal方式发送pCond,
* 这个过程是一个原子操作。
* 收到pCond后,此函数返回0,并再次lock pMutex。
*
* 如果收到其它Signal,此函数也返回0,这是一种虚假唤醒(Spurious Wakeup),
* 因此需要再判断相应数据的值
*
* 调用此函数的Thread必须先成功lock pMutex,否则此函数直接返回EINVAL
*/
int pthread_cond_wait(pthread_cond_t *pCond, pthread_mutex_t *pMutex);
/*
* 与pthread_cond_wait()类似
* 不过在阻塞到绝对时间pAbstime后,返回ETIMEDOUT
*/
int pthread_cond_timedwait(pthread_cond_t *pCond, pthread_mutex_t *pMutex, struct timespec *pAbstime);
/*
* 将阻塞在pCond上的Thread置为Ready
* 如果有多个Thread阻塞,则解除优先级最高的Thread
* 如果没有Thread阻塞,则直接返回
*/
int pthread_cond_signal(pthread_cond_t *pCond);
/*
* 将阻塞在pCond上的所有Thread置为Ready
* 如果没有Thread阻塞,则直接返回
*/
int pthread_cond_broadcast(pthread_cond_t *pCond);
写个例子
/*
* 版权所有 公众号 VxWorks567
*/
#include <stdio.h> /* printf() */
#include <unistd.h> /* sleep() */
#include <pthread.h> /* pthread_create() */
static pthread_mutex_t mutexid;
static pthread_cond_t condid;
static int data = 0;
static void *thread1(void *arg)
{
pthread_mutex_lock(&mutexid);
printf("\nCondition Variable: in thread1, pthread_mutex_lock\n");
printf("Condition Variable: in thread1, data = %d\n", data);
printf("Condition Variable: in thread1, pthread_cond_wait begin\n\n");
pthread_cond_wait(&condid, &mutexid);
printf("\nCondition Variable: in thread1, pthread_cond_wait end\n\n");
printf("Condition Variable: in thread1, data = %d\n", data);
pthread_mutex_unlock(&mutexid);
printf("Condition Variable: in thread1, pthread_mutex_unlock\n");
return NULL;
}
static void *thread2(void *arg)
{
sleep(1);
pthread_mutex_lock(&mutexid);
printf("\nCondition Variable: in thread2, pthread_mutex_lock\n");
data = 1;
printf("Condition Variable: in thread2, data = %d\n", data);
printf("Condition Variable: in thread2, pthread_cond_signal begin\n");
pthread_cond_signal(&condid);
printf("Condition Variable: in thread2, pthread_cond_signal end\n");
printf("Condition Variable: in thread2, pthread_mutex_unlock begin\n");
pthread_mutex_unlock(&mutexid);
printf("Condition Variable: in thread2, pthread_mutex_unlock end\n");
return NULL;
}
int testPosixCond()
{
pthread_t tid1;
pthread_t tid2;
sleep(1);
pthread_mutex_init(&mutexid, NULL);
pthread_cond_init(&condid, NULL);
printf("\nCondition Variable: in main thread, pthread_mutex_init&pthread_cond_init\n");
pthread_create(&tid1, NULL, &thread1, NULL);
pthread_create(&tid2, NULL, &thread2, NULL);
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
pthread_cond_destroy(&condid);
pthread_mutex_destroy(&mutexid);
printf("Condition Variable: in main thread, pthread_cond_destroy&pthread_mutex_destroy\n");
return 0;
}
看出这个Condition Variable与二进制信号量类似的地方了吗