• 忘掉天地
  • 仿佛也想不起自己
bingliaolongBingliaolong  2020-05-21 14:45 Aet 隐藏边栏 |   抢沙发  11 
文章评分 7 次,平均分 5.0

等待事件或其他条件

  1. 如果一个线程正等待着第二个线程完成一项任务,它有几个选择。
    1. 可以一直检测共享数据(由互斥量保护)中的标识,并且让第二个线程在完成任务时设置该标识。
      浪费资源
    2. 使用std::this_thread::sleep_for(),让等待的线程在检查之间休眠一会儿
      得到正确的休眠时间比较难
    3. 使用C++标准库提供的工具来等待事件本身。
  2. 等待由另一个线程触发一个事件的最基本机制是条件变量

第二种选择:

  1. 解锁互斥量
  2. 解锁之后让函数休眠一段时间,这段时间之后再次锁定
  3. 在解锁的这段时间里,其他线程有机会获取它并设置标识

第三个选择

  1. 通过另一线程触发等待事件的机制是最基本的唤醒方式,这种机制就称为“条件变量”。
  2. 从概念上来说,条件变量与某些事件或其他条件相关,并且一个或多个线程可以等待该条件被满足。
  3. 当某个线程已经确定条件得到满足,它就可以通知一个或多个正在条件变量上进行等待的线程,以便唤醒它们并让它们继续处理。

等待条件达成

condition_variable

  1. 仅限于和std::mutex一起工作

condition_variable_any

  1. 可以与符合类似互斥量的最低标准的任何东西一起工作

  1. 首先创建一个在两个线程间传递数据的队列
  2. 当数据准备就绪时,使用lock_guard去锁定保护队列的互斥量,并将数据压入队列
  3. 然后在condition_variable的实例上调用notify_one函数,以通知等待中的线程(如果有的话)
  4. 在等待中的线程中,以unique_lock锁定互斥量
    1. 等待中的线程必须在等待期间解锁互斥量,并在这之后重新将其锁定,lock_guard没有这样的灵活性
  5. 然后在condition_variable上调用wait,传入锁对象以及表示正在等待的条件lambda函数(检查到队列不为空时,即有数据处理时)
  6. wait接下来检查判断条件,整个lambda表达式返回的结果参数为true时,返回。如果不满足条件,也就是队列中没有数据处理,lambda返回falsewait将会解锁该互斥量,并将该线程置于等待或者阻塞状态。
  7. unique_lock不仅适用于对wait的调用,还可用于有待处理但未处理的数据

使用条件变量建立一个线程安全队列

本文为原创文章,版权归所有,欢迎分享本文,转载请保留出处!

bingliaolong
Bingliaolong 关注:0    粉丝:0 最后编辑于:2023-05-24
Everything will be better.

发表评论

表情 格式 链接 私密 签到
扫一扫二维码分享