【多线程编程学习笔记10】使用条件变量实现线程同步

本文介绍了C语言在Linux环境下如何利用条件变量进行线程同步,详细阐述了条件变量的初始化、阻塞线程、解除阻塞及销毁等操作,并通过一个实例展示了条件变量在等待变量条件成立时的应用,强调了条件变量与互斥锁的配合使用,以避免效率问题和资源争夺。

申明:本学习笔记是在该教程的基础上结合自己的学习情况进行的总结,不是原创,想要看原版的请看C语言中文网的多线程编程(C语言+Linux),该网站有很多好的编程学习教程,尤其是关于C语言的。


假设一个进程中包含多个线程,这些线程共享变量 x,我们希望某个(或某些)线程等待 "x==10’ 条件成立后再执行后续的代码,该如何实现呢?

您可能想到用 while 循环实现,例如:

void* threadFun(void * args){
    while(x != 10){
        sleep(5);
    }
    // 待条件成立后,执行后续的代码
}

当线程执行此函数时,会判断 x 的值是否等于 10,如果不等则间隔 5 秒后再重复判断,直到 x 的值等于 10 ,线程才能执行后续的代码。

直观上看,while 循环确实能够阻塞线程,但这种方法存在严重的效率问题。当线程因条件不成立进入等待状态时,如果此时恰好有另一个线程将 x 的值改为 10,该线程必须等待 5 秒后才能继续执行。如果我们将等待时间缩短(或者直接将 sleep(5) 注释掉),线程将反复判断 x 的值是否等于 10,它可能会一直霸占着 CPU 资源,导致其它线程无法执行,x 变量的值会出现“长时间不改变”的情况。

针对类似的场景,我们推荐您用条件变量来实现。和互斥锁、信号量类似,条件变量本质也是一个全局变量,它的功能是阻塞线程,直至接收到“条件成立”的信号后,被阻塞的线程才能继续执行。

一个条件变量可以阻塞多个线程,这些线程会组成一个等待队列。当条件成立时,条件变量可以解除线程的“被阻塞状态”。也就是说,条件变量可以完成以下两项操作:

  • 阻塞线程,直至接收到“条件成立”的信号;
  • 向等待队列中的一个或所有线程发送“条件成立”的信号,解除它们的“被阻塞”状态。

为了避免多线程之间发生“抢夺资源”的问题,条件变量在使用过程中必须和一个互斥锁搭配使用。如果您不了解互斥锁或者对互斥锁一知半解,请先阅读《Linux互斥锁实现线程同步》一文。

条件变量的具体用法

POSIX 标准中,条件变量用 pthread_cond_t 类型的变量表示,此类型定义在<pthread.h>头文件中。举个例子:

#include <pthread.h>pthread_cond_t myCond;

由此,我们就成功创建了一个条件变量。要想使用 myCond 条件变量,还需要进行初始化操作。

1) 初始化条件变量

初始化条件变量的方式有两种,一种是直接将 PTHREAD_COND_INITIALIZER 赋值给条件变量,例如:

pthread_cond_t myCond = PTHREAD_COND_INITIALIZER;

还可以借助 pthread

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

机载软件与适航

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值