多线程编程:条件变量pthread_cond_t

等待条件有两种方式:条件等待pthread_cond_wait()和计时等待pthread_cond_timedwait(),其中计时等待方式如果在给定时刻前条件没有满足,则返回ETIMEDOUT,结束等待,其中abstime以与time()系统调用相同意义的绝对时间形式出现,0表示格林尼治时间1970年1月1日0时0分0秒。
无论哪种等待方式,都必须和一个互斥锁配合,以防止多个线程同时请求pthread_cond_wait()(或pthread_cond_timedwait(),下同)的竞争条件(Race Condition)。mutex互斥锁必须是普通锁(PTHREAD_MUTEX_TIMED_NP)或者适应锁(PTHREAD_MUTEX_ADAPTIVE_NP),且在调用pthread_cond_wait()前必须由本线程加锁(pthread_mutex_lock()),而在更新条件等待队列以前,mutex保持锁定状态,并在线程挂起进入等待前解锁。在条件满足从而离开pthread_cond_wait()之前,mutex将被重新加锁,以与进入pthread_cond_wait()前的加锁动作对应。
激发条件有两种形式,pthread_cond_signal()激活一个等待该条件的线程,存在多个等待线程时按入队顺序激活其中一个;而pthread_cond_broadcast()则激活所有等待线程。
示例代码:
#include <iostream> #include <pthread.h> #include <unistd.h> using namespace std; pthread_cond_t qready = PTHREAD_COND_INITIALIZER; /*初始构造条件变量*/ pthread_mutex_t qlock = PTHREAD_MUTEX_INITIALIZER; /*初始构造锁*/ int x = 10; int y = 20; void *func1(void *arg){ cout<<"func1 start"<<endl; pthread_mutex_lock(&qlock); while(x<y) { pthread_cond_wait(&qready,&qlock); } pthread_mutex_unlock(&qlock); sleep(3); cout<<"func1 end"<<endl; } void *func2(void *arg){ cout<<"func2 start"<<endl; pthread_mutex_lock(&qlock); x = 20; y = 10; cout<<"has change x and y"<<endl; pthread_mutex_unlock(&qlock); if(x > y){ pthread_cond_signal(&qready); } cout<<"func2 end"<<endl; } int main(int argc,char **argv){ pthread_t tid1,tid2; int iRet; iRet = pthread_create(&tid1,NULL,func1,NULL); if(iRet){ cout<<"pthread 1 create error"<<endl; return iRet; } sleep(2); iRet = pthread_create(&tid2,NULL,func2,NULL); if(iRet){ cout<<"pthread 2 create error"<<endl; return iRet; } sleep(5); return 0; }
浙公网安备 33010602011771号