//条件变量的定义
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;// seconds
long 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 sum
for(int i =1;i<=100;i++){
sum +=i;
}
//将结果存放到Result
Result *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 get
pthread_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 sum
for(int i =1;i<=100;i++){
sum +=i;
}
//将结果存放到Result
Result *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 get
pthread_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;
}
代码运行结果: