zoukankan      html  css  js  c++  java
  • C++11 并发-锁与条件变量

    互斥元

    std::mutex

    std::lock_guard

    实现互斥元的 RAII 惯用语法,它在构造时锁定所给的互斥元,在析构时将互斥元解锁,从而保证被锁定的互斥元始终被正确解锁

    std::unique_lock

    提供了lock()、try_lock()和unlock()三个成员函数,它们会调用底层互斥元上同名的成员函数去做实际的工作,并且只是更新在std::unique_lock实例内部的一个标识,来表示该实例当前实例是否拥有此互斥元(如果标识表示了该实例拥有互斥元,则析构函数必须调用unlock();如果不拥有互斥元,则一定不能调用unlock())。因此std::unique_lock对象的大小通常大于std::lock_guard对象;使用std::unique_lock时,由于需要对标识进行相应的更新或判断在性能上会有些许损失

    其灵活性还体现在可以在作用域之间转移锁的所有权

    std::lock

    待补充

    加解锁的一些未定义行为

    待补充

    共享互斥元

    boost::shared_mutex

    boost::unique_lock<boost::shared_mutex>

    写锁

    boost::shared_lock<boost::shared_mutex>

    读锁

    递归互斥元

    std::recursive_mutex

    待补充

    条件变量

    从概念上说,条件变量与某些事件或其他条件相关,并且一个或多个线程可以等待该条件被满足。当某个线程已经确定条件得到满足,它就可以通知一个或多个正在条件变量上进行等待的线程,以便唤醒它们并让它们继续处理

    std::condition_variable

    等待操作

    调用wait()函数需要传入锁对象,以及表示正在等待的条件的判断函数(判断函数可以使用lambda表达式)

    调用wait()函数时,其内部首先会调用所提供的判断函数:

    • 如果满足条件(lambda返回true)则返回,当前线程继续执行
    • 如果不满足条件,则将当前线程置于等待状态(加入这个条件变量的等待队列)并解锁互斥元

    当wait函数被唤醒时(其他线程调用通知或伪唤醒):

    • 重新获取互斥元(加锁)
    • 执行上面的一系列判断及相应操作

    伪唤醒

    当等待线程重新获取互斥元并检查条件时,如果它并非直接响应另一个线程的通知,即伪唤醒

    丢失通知

    在wait操作的实现流程的分析中,判断不满足条件与之后的所有处理并非是个原子操作,因此当前线程进入等待状态前,有可能其他线程的通知已经发出,这样就丢失了通知。具体实例可参考:线程池学习

    std::condition_variable_any

    灵活性更大,所以可能会有大小、性能或者操作系统资源方面的额外代价

  • 相关阅读:
    设置debian6源
    debian7编译安装tengine添加lua和ldap模块
    elasticsearch5使用snapshot接口备份索引
    logstash5生成init脚本后台启动
    Xpack集成LDAP
    debian安装filebeat5.5收集nginx日志
    kibana5画图
    安装Xtrabackup,设置定时备份msyql数据库
    编译安装nrpe,配置监控mysql端口和主从状态
    编译安装keepalived,实现双主mysql高可用
  • 原文地址:https://www.cnblogs.com/wangzhiyi/p/13659334.html
Copyright © 2011-2022 走看看