• (十)线程同步


    1. 线程同步的使用原则

    • 首要尽量最低限度共享对象,减少需要同步的场合,避免一个对象暴露给别的线程;
    • 其次是使用高级的并发编程构件,如线程安全的队列等;
    • 最后不得已必须使用底层同步原语来保护共享对象时,只使用非递归的互斥锁和条件变量;

    2. 互斥锁

    参考: std::mutex

    互斥锁单独使用,主要是为了保护共享数据.
    std::mutex的使用原则是, 使用RAII手法封装mutex的创建/销毁/加锁/解锁这四个操作, 保证锁的生效期间等于一个作用域, 不会因异常而忘记解锁. RAII能够保证加锁/解锁在同一个线程, 能够保证自动解锁和避免重复解锁.

    std::lock_guard 是互斥封装器,为在作用域块期间占有互斥提供便利 RAII 风格机制。
    参考std::lock_guard

    std::unique_lock 是通用互斥包装器,允许延迟锁定、锁定的有时限尝试、递归锁定、所有权转移和与条件变量一同使用。
    参考std::unique_lock

    3. 条件变量

    参考: std::condition_variable

    条件变量就是一个或多个线程等待某个布尔表达式为真,即等待别的线程"唤醒"它.
    条件变量只有一种正确使用的方式:

    • 对于wait端:
      • 必须与mutex一起使用, 该布尔表达式的读写需受此mutex保护;
      • 在mutex已上锁时才能调用wati();
      • 把判断布尔条件和wait()放到while循环中. 必须使用while循环来等待条件变量,而不能用if语句,原因是spurious wakeup(虚假唤醒).
    • 对于notify端:
      • 在notify前一般要修改布尔表达式;
      • 修改布尔表达式通常要用mutex保护;
      • 区分notify_one和notify_all.
  • 相关阅读:
    第一份随笔
    慢哈希算法
    彩虹表
    基于Wireshark验证网站口令认证传输方案
    electron学习笔记2
    基于原型的软件需求获取
    《小学四则运算练习软件》结对项目报告
    201571030109 小学四则运算练习软件项目报告
    201571030109 《构建之法》速读
    个人学期总结
  • 原文地址:https://www.cnblogs.com/walkinginthesun/p/9375240.html
Copyright © 2020-2023  润新知