当前位置:网站首页 > C++编程 > 正文

c++ 条件变量性能(c++11 条件变量wait函数)



互斥量是多线程间同时访问某一共享变量时,保证变量可被安全访问的手段。但单靠互斥量无法实现线 程的同步。线程同步是指线程间需要按照预定的先后次序顺序进行的行为。C++11对这种行为也提供了 有力的支持,这就是条件变量。条件变量位于头文件下。【官方说明文档】。

条件变量使用过程:

  1. 拥有条件变量的线程获取互斥量。
  2. 循环检查某个条件,如果条件不满足则阻塞直到条件满足;如果条件满足则向下执行。
  3. 某个线程满足条件执行完之后调用notify_one或notify_all唤醒一个或者所有等待线程。

条件变量提供了两类操作:wait和notify。这两类操作构成了多线程同步的基础。

函数原型:

 
  

包含两种重载,第一种只包含unique_lock对象,另外一个Predicate 对象(等待条件),这里必须使用 unique_lock,因为wait函数的工作原理

  • 当前线程调用wait()后将被阻塞并且函数会解锁互斥量,直到另外某个线程调用notify_one或者
    notify_all唤醒当前线程;一旦当前线程获得通知(notify),wait()函数也是自动调用lock(),同理不
    能使用lock_guard对象。

  • 如果wait没有第二个参数,第一次调用默认条件不成立,直接解锁互斥量并阻塞到本行,直到某一
    个线程调用notify_one或notify_all为止,被唤醒后,wait重新尝试获取互斥量,如果得不到,线程
    会卡在这里,直到获取到互斥量,然后无条件地继续进行后面的操作。

  • 如果wait包含第二个参数,如果第二个参数不满足,那么wait将解锁互斥量并堵塞到本行,直到某
    一个线程调用notify_one或notify_all为止,被唤醒后,wait重新尝试获取互斥量,如果得不到,线
    程会卡在这里,直到获取到互斥量,然后继续判断第二个参数,如果表达式为false,wait对互斥
    量解锁,然后休眠,如果为true,则进行后面的操作。


函数原型:

 
  

和wait不同的是,wait_for可以执行一个时间段,在线程收到唤醒通知或者时间超时之前,该线程都会 处于阻塞状态,如果收到唤醒通知或者时间超时,wait_for返回,剩下操作和wait类似。

函数原型:

 
  

与wait_for类似,只是wait_until可以指定一个时间点,在当前线程收到通知或者指定的时间点超时之 前,该线程都会处于阻塞状态。如果超时或者收到唤醒通知,wait_until返回,剩下操作和wait类似 。

函数原型:

 
  

解锁正在等待当前条件的线程中的一个,如果没有线程在等待,则函数不执行任何操作,如果正在等待的线程多于一个,则唤醒的线程是不确定的。随机唤醒。

函数原型:

 
  

解锁正在等待当前条件的所有线程,如果没有正在等待的线程,则函数不执行任何操作。

 
  

(main.cc)

 
  

代码中用到了std::lock_guard,它利用RAII机制可以保证安全释放mutex。

 
  

可以改为:

 
  

两种写法效果是一样的,但是后者更简洁,条件变量会先检查判断式是否满足条件,如果满足条件则重 新获取mutex,然后结束wait继续往下执行;如果不满足条件则释放mutex,然后将线程置为waiting状 态继续等待。

这里需要注意的是,wait函数中会释放mutex,而lock_guard这时还拥有mutex,它只会在出了作用域 之后才会释放mutex,所以这时它并不会释放,但执行wait时会提前释放mutex。

从语义上看这里使用lock_guard会产生矛盾,但是实际上并不会出问题,因为wait提前释放锁之后会处 于等待状态,在被notify_one或者notify_all唤醒后会先获取mutex,这相当于lock_guard的mutex在 释放之后又获取到了,因此,在出了作用域之后lock_guard自动释放mutex不会有问题。

这里应该用unique_lock,因为unique_lock不像lock_guard一样只能在析构时才释放锁,它可以随时释 放锁,因此在wait时让unique_lock释放锁从语义上更加准确。

 
  

(main.cpp)

 
  

条件变量是一个对象,能够在通知恢复之前阻止调用线程。它使用在调用其等待函数之一时锁定线程。线程将保持阻塞状态,直到被另一个调用同一对象上的通知函数的线程唤醒。

在这里插入图片描述

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

版权声明


相关文章:

  • 简单好玩的编程代码(c++简单好玩的编程代码)2025-05-30 21:46:56
  • pilows翻译成英语(pigcasso翻译英语)2025-05-30 21:46:56
  • tcp坐标系(tcp和工具坐标系的关系)2025-05-30 21:46:56
  • dcp7060d纸盒无纸(7360纸盒无纸)2025-05-30 21:46:56
  • tcping工具(tcping工具怎么安装)2025-05-30 21:46:56
  • conv2d参数解释(conv2d的参数)2025-05-30 21:46:56
  • conv1D什么意思(cond是什么意思)2025-05-30 21:46:56
  • cnn是哪个国家的新闻媒体抖音(cnn是哪个国家的电视台)2025-05-30 21:46:56
  • 跨域请求携带cookie(跨域 cookies)2025-05-30 21:46:56
  • uchar类型(uchar类型的指针a,其地址为0x0012ff38,b,c)2025-05-30 21:46:56
  • 全屏图片