当前位置:网站首页 > 编程语言 > 正文

条件变量和互斥量(条件变量和互斥锁)



我们了解互斥量和条件变量之前,我们先来看一下为什么要有互斥量和条件变量这两个东西,了解为什么有这两东西之后,理解起来后面的东西就简单很多了!!!

先来看下面这段简单的代码:

上述代码功能大致就是在线程tha和thb中运行函数print,每个线程对g_num进行加加一次,最后加出来的g_num的值应该是10,那么我们现在来看结果:

我们看到运行结果,为什么打印结果最后,按理来说两个线程各加五次,最后结果应该是10呀,怎么会是9呢?

如上图所示,是因为++这个运算符不是原子操作(不会被线程调度机制打断的操作),我们可以将g_num设置为原子数,改为

将g_num设置为原子操作数之后,在++阶段就不会被线程调度机制给打断,我们来看运行结果:

运行结果是我所期望的但是中间那块又出了一点小状况连着打着两个4,两个6,这种情况该怎么办呢?

下面就该说道我们的互斥锁了:

在上述代码中我们使用了共享资源----->全局量g_num,两个线程同时对g_num进行++操作,为了保护共享资源,在线程里也有这么一把锁——互斥锁(mutex),互斥锁是一种简单的加锁的方法来控制对共享资源的访问,互斥锁只有两种状态,即上锁( lock )和解锁( unlock )。

来看下面代码:

我们来看运行结果:符合我们最初的预期。

打开官方文档,可以看到

创建锁对象只有这个方法,拷贝构造被删除了 。

对于互斥锁的lock和unlock我们都很熟悉了,下面来说一下这个成员函数!

try_lock字面意思就是说尝试上锁,如果上锁成功,返回true,上锁失败则返回false,但是如果上锁失败,他还是会接着往下运行,不会像lock哪运被阻塞在上锁那块,所以try_lock必须得在循环中使用:

我们来看运行结果:

unlock of unowned mutex,这玩意思就是说你在给个没上锁的互斥锁解锁,所以报这错误,因此try_lock搁在普通语句中,会有很大的问题,现命我们演示一下将这玩意放到循环中去弄一边:

我们来看运行结果:

运行结果符合我们的预期,但是try_lock这个函数有个不好处是太损耗资源了,当它加锁失败时,一直尝试加锁一直尝试加锁,损耗CPU资源。

框住这三个函数较为重要,下面着重来说下面这三个函数: 这里顺便说一下,下面代码将会是条件变量和互斥锁的结合使用,至于为什么要将互斥锁和条件变量一起使用,原因就是互斥锁状态太单一了,而条件变量允许阻塞,接收信号量等刚好弥补了互斥锁的缺陷所以这些一起使用!!!

这三个函数呢,通过一个小实验来实现,通过多线程分别打印123一直到100:

上面代码解析:

运行结果:

我们可以看到上述代码最后唤醒其他线程使用的是notify_all()函数,notify_all()函数作用就是环球其他阻塞的函数,然后因为isready这个数的存在,所以就会选择合适的线程来进行执行,如果我们使用notify_one()呢,先来说下notify_one()函数的作用是什么。notify_one()函数是唤醒其他线程(随机唤醒,这道题中不适合,因为如果打印完A之后唤醒了C线程那么就会一直阻塞在那块)

我们试一下notify_one()函数,可以发现这玩意确实会堵塞在那块:

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注脚本之家的更多内容!

到此这篇条件变量和互斥量(条件变量和互斥锁)的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!

版权声明


相关文章:

  • 国内github访问下载太慢解决办法(国内github访问下载太慢解决办法)2025-08-09 22:27:10
  • samba 拒绝访问(windows访问samba拒绝)2025-08-09 22:27:10
  • xd是什么意思的缩写(xd是什么英文的缩写)2025-08-09 22:27:10
  • qq怎么扫描二维码登录(qq怎么扫描二维码登录支持手机)2025-08-09 22:27:10
  • bt200协议(bt协议详解)2025-08-09 22:27:10
  • 接口402(接口402报错)2025-08-09 22:27:10
  • 代码网站(瓦罗兰特准星代码网站)2025-08-09 22:27:10
  • 宽带 nat类型 在线检测(查看宽带nat类型)2025-08-09 22:27:10
  • 101规约详细介绍及报文解析(101规约报文解析实例)2025-08-09 22:27:10
  • Xmouse下载(xmouse进游戏用不了)2025-08-09 22:27:10
  • 全屏图片