• 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

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

  • 相关阅读:
    第六次作业--结对编程第二次
    第四次作业——项目选题报告
    第五次作业——结对
    第三次作业——团队项目展示
    第二次作业——个人项目实战
    第一次作业-准备
    码农开富农,锄头得先拿
    一个关于狗记录的Java练习
    一个随手练的题目后面再弄一个带面版的
    java拓荒者
  • 原文地址:https://www.cnblogs.com/wangzhiyi/p/13659334.html
Copyright © 2020-2023  润新知