广东城乡建设厅网站首页,做电商要不要公司网站,百度开户代理商,网站建设邀标方案一、条件变量的概念
如果说互斥锁是用于同步线程对共享数据的访问的话#xff0c;那么条件变量则是用于在线程之间同步共享数据的值。条件变量提供了一种线程间的通知机制#xff1a;当某个共享数据达到某个值的时候#xff0c;唤醒等待这个共享数据的线程。如下图所示那么条件变量则是用于在线程之间同步共享数据的值。条件变量提供了一种线程间的通知机制当某个共享数据达到某个值的时候唤醒等待这个共享数据的线程。如下图所示 二、条件变量相关函数
1.pthread_cond_init()初始化条件变量 参数解释
第一个参数cond条件变量 第二个参数attr条件变量属性通常传NULL表示使用默认属性
2.pthread_cond_wait()等待条件变量满足 功能阻塞等待一个条件变量(等待唤醒)并解除相应的锁资源
参数解释 第一个参数cond条件变量 第二个参数mutex是用于保护条件变量的互斥锁以确保pthread_cond_wait操作的原子性。在调用pthread_cond_wait之前必须确保互斥锁mutex已经加锁否则将会出现多个线程同时要进入等待队列的情况导致不可预期的结果。pthread_cond_wait在执行时首先把调用线程放入条件变量的等待队列中然后将互斥锁解锁。从pthread_cond_wait开始执行到其调用线程被放入条件变量的等待队列之间的这段时间内pthread_cond_signal和pthread_cond_broadcast等函数不会修改条件变量的值。也就是说当线程在进出条件变量的等待队列的时候是不会去唤醒等待队列中的其他线程的。当pthread_cond_wait函数成功返回时互斥锁mutex将再次被锁上这是pthread_cond_wait函数内部做的事情就是为了防止在唤醒某个线程的时候和其他线程进出等待队列发生冲突。如果有一个线程正在进入等待队列这时想要唤醒某个线程时就需要加锁就会加锁失败要等正在进入等待队列的线程彻底进去之后解锁然后才能加锁去唤醒想要唤醒的线程然后再加锁然后出等待队列的之后在进行解锁。
注意: 线程被唤醒pthread_cond_wait函数返回时解除阻塞并重新申请获取互斥锁。
3.pthread_cond_broadcast()唤醒全部在等待条件变量的线程 参数解释
参数cond条件变量
4.pthread_cond_signal()唤醒一个在等待条件变量的线程随机唤醒一个 参数解释
参数cond条件变量
5.pthread_cond_destroy()销毁条件变量 参数解释
参数cond条件变量
三、条件变量的使用
【例】有两个线程A和B在等待队列中给一个数组buff当从键盘上向buff中写入数据之后就随机唤醒一个线程去读取buff中的内容并输出当从键盘上向buff中写入end的时候唤醒所有正在等待的线程让所有线程退出。
上例中条件变量就是用户从键盘输入的数据线程A和线程B根据条件变量的情况被唤醒。
代码如下
#includestdio.h
#includestdlib.h
#includeunistd.h
#includepthread.h
#includestring.h
#includesemaphore.hpthread_cond_t cond;
pthread_mutex_t mutex;char buff[128]{0};void* fun_a(void* arg)
{while(1){//在线程A进入等待队列之前加锁,如果加锁成功线程A进入等待队列这时别的线程不可以进入等待队列pthread_mutex_lock(mutex);//线程A进入等待队列中线程B被阻塞解锁线程A被唤醒加锁pthread_cond_wait(cond,mutex);//在线程A从等待队列出来之后解锁这时别的线程就可以进入等待队列pthread_mutex_unlock(mutex);if(strncmp(buff,end,3)0) {break;}else{printf(线程A输出%s,buff);}}printf(线程A结束\n);
}void* fun_b(void* arg)
{while(1){//在线程B进入等待队列之前加锁,如果加锁成功线程B进入等待队列这时别的线程不可以进入等待队列pthread_mutex_lock(mutex);//线程B进入等待队列中线程B被阻塞解锁线程B被唤醒加锁pthread_cond_wait(cond,mutex);//在线程B从等待队列出来之后解锁这时别的线程就可以进入等待队列pthread_mutex_unlock(mutex);if(strncmp(buff,end,3)0){break;}else{printf(线程B输出%s,buff);}}printf(线程B结束\n);
}int main()
{pthread_mutex_init(mutex,NULL);pthread_cond_init(cond,NULL);pthread_t id1,id2;pthread_create(id1,NULL,fun_a,NULL);pthread_create(id2,NULL,fun_b,NULL);while(1){fgets(buff,128,stdin);if(strncmp(buff,end,3)0){//唤醒所有pthread_cond_broadcast(cond);break;}else{//随机唤醒一个pthread_cond_signal(cond);}}pthread_join(id1,NULL);pthread_join(id2,NULL);pthread_mutex_destroy(mutex);pthread_cond_destroy(cond);exit(0);
}运行结果