//条件变量的定义
pthread_cond_t cond;
int pthread_cond_init(pthread_cond_t *restrict cond,pthread_condattr_t *restrict attr);
int pthread_cond_destroy(pthread_cond_t *restrict cond);
返回:成功返回0 出错返回错误编号
//线程等待
int pthread_cond_wait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex);
//线程等待一段时间,如果到时间就返回
int pthread_cond_timewait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex,const struct timespec *restrict timeout);
返回:成功返回0 出错返回错误编号
struct timespec{time_t tv_sec;// secondslong tv_nsec //nanoseconds
}
int pthread_cond_signal(pthread_cond_t *cond);
int pthread_cond_broadcast(pthread_cond_t *cond);
#include
#include
#include
/*一个线程赋值计算结果,一个线程负责获取结果当计算结果的线程没有执行完毕,获取结果的线程要等待(阻塞)
*/
typedef struct{//共享资源int res;//存放运算结果int is_wait;//用户给出用于判断的条件pthread_cond_t cond;//定义条件变量pthread_mutex_t mutex;//定义互斥锁
}Result;//计算并将结果放置Result中的线程运行函数
void* set_fn(void *arg){int sumfor(int i =1;i<=100;i++){sum +=i;}//将结果存放到ResultResult *r = (Result*)arg;r->res = sum;//对两个线程共享的判断条件进行保护pthread_mutex_lock(&r-mutex);//判断获取结果的线程是否准备好,只有准备好了才可结束。is_wait为0代表没有准备好while(!r->is_wait){//等待获取结果的线程pthread_mutex_unlock(&r-mutex);Sleep(10000);pthread_mutex_lock(&r-mutex);}pthread_mutex_unlock(&r-mutex);//唤醒(通知)等待的那个获取结果的线程pthread_cond_broadcast(&r->cond)return(void*)0;
}//获得结果的线程运行函数
void* get_fn(void *arg){Result *r = (Result*)arg;//对两个线程共享的判断条件进行保护(加锁)//两个线程对判断条件操作是互斥的pthread_mutex_lock(&r-mutex);//代表获取结果的线程已经准备好了r->is_wait = 1;//获取结果的线程等待,就是自身线程阻塞//&r->mutex这个锁是用于保护队列pthread_cond_wait(&r->cond,&r->mutex);//线程唤醒后,释放锁pthread_mutex_unlock(&r->mutex);int res = r->res;printf("ox%lx get sum is %d\n",pthread_self(),res);return(void*)0;
}int main(void){int err;//定义线程标识符cal getpthread_t cal, get;//结构体赋值Result r;r.is_wait = 0;//条件变量,互斥锁初始化pthread_cond_init(&r.cond,null);pthread_mutex_init(&r.mutex,null);//创建两个线程,并给与赋值//启动获取结果的线程if ((err = pthread_create(&get, NULL, get_fn, (void*)&r)) != 0) {perror("pthread_create error");}//启动计算结果的线程if ((err = pthread_create(&cal, NULL, set_fn, (void*)&r)) != 0) {perror("pthread_create error");}//主线程要等两个子线程执行完毕pthread_join(get,null);pthread_join(cal,null);//条件变量和互斥锁的销毁pthread_cond_destroy(&r.cond);pthread_mutex_destroy(&r.mutex);return 0;
}
程序结果输出:

对pthread_cond_wait函数为什么在后面要加上 释放锁
//对两个线程共享的判断条件进行保护(加锁)
//两个线程对判断条件操作是互斥的pthread_mutex_lock(&r-mutex);
//代表获取结果的线程已经准备好了r->is_wait = 1;//获取结果的线程等待,就是自身线程阻塞
//&r->mutex这个锁是用于保护队列pthread_cond_wait(&r-cond,&r->mutex);
//线程唤醒后,释放锁pthread_mutex_unlock(&r-mutex);

为什么pthread_cond_wait(&r-cond,&r->mutex)线程等待函数要在,释放锁函数的前面?
正如图片所展示的,在执行pthread_cond_wait时第一步先锁释放(这个释放锁和上面那个加锁是一对的),同时又上锁(此时上锁是用于保护线程存放到等待队列),线程自己插入条件变量的等待队列中,此时再解锁等待唤醒,唤醒后在上锁和最后那个释放锁是一对的。

#include
#include
#include
/*一个线程赋值计算结果,多个线程负责获取结果当计算结果的线程没有执行完毕,获取结果的线程要等待(阻塞)
*/
typedef struct{//共享资源int res;//存放运算结果int couter;//用于统计获取结果线程的数量pthread_cond_t cond;//定义条件变量pthread_mutex_t mutex;//定义互斥锁
}Result;//计算并将结果放置Result中的线程运行函数
void* set_fn(void *arg){int sumfor(int i =1;i<=100;i++){sum +=i;}//将结果存放到ResultResult *r = (Result*)arg;r->res = sum;//对两个线程共享的判断条件进行保护pthread_mutex_lock(&r-mutex);//判断获取结果的线程是否多余2个,只有2个以上的线程了才可继续运行。否则就等待while(r->couter< 2){//等待获取结果的线程pthread_mutex_unlock(&r-mutex);Sleep(10000);pthread_mutex_lock(&r-mutex);}pthread_mutex_unlock(&r-mutex);//唤醒(通知)等待的那个获取结果的线程pthread_cond_broadcast(&r->cond)return(void*)0;
}//获得结果的线程运行函数
void* get_fn(void *arg){Result *r = (Result*)arg;//对两个线程共享的判断条件进行保护(加锁)//两个线程对判断条件操作是互斥的pthread_mutex_lock(&r-mutex);//代表获取结果的线程已经准备好了r->couter ++;//获取结果的线程等待,就是自身线程阻塞//&r->mutex这个锁是用于保护队列pthread_cond_wait(&r-cond,&r->mutex);//线程唤醒后,释放锁pthread_mutex_unlock(&r-mutex);int res = r->res;printf("ox%lx get sum is %d\n",pthread_self(),res);return(void*)0;
}int main(void){int err;//定义线程标识符cal getpthread_t cal,get1,get1;//结构体赋值Result r;r.couter = 0;//条件变量,互斥锁初始化pthread_cond_init(&r.cond,null);pthread_mutex_init(&r.mutex,null);//启动获取结果的线程两个if ((err = pthread_create(&get1, NULL, get_fn, (void*)&r)) != 0) {perror("pthread_create error");}if ((err = pthread_create(&get2, NULL, get_fn, (void*)&r)) != 0) {perror("pthread_create error");}//启动计算结果的线程if ((err = pthread_create(&cal, NULL, set_fn, (void*)&r)) != 0) {perror("pthread_create error");}//主线程要等两个子线程执行完毕pthread_join(get1,null);pthread_join(get2,null);pthread_join(cal,null);//条件变量和互斥锁的销毁pthread_cond_destroy(&r.cond);pthread_mutex_destroy(&r.mutex);return 0;
}
代码运行结果:
