条件变量和原子操作不能混合使用

主要观点:使用std::condition_variable时要记住所有在等待谓词中访问的变量必须在互斥锁下更改,否则易违反此规则导致错误;典型工作池工作函数示例及通过添加std::atomic<bool>来解决线程终止问题,但此代码存在竞态条件可能偶尔挂起;原因是std::atomic虽能修复 ThreadSanitizer 报告但不能解决竞态,wait(pred)等价于特定循环,可能出现线程检查杀标志未设置但还未进入等待状态,主进程就设置标志并调用notify_all,导致通知状态不“粘性”,从而产生死锁;正确做法是在析构函数中获取互斥锁来确保杀标志状态在检查谓词状态和条件变量工作之间不会改变。

关键信息

  • std::condition_variable使用规则及易违反情况。
  • 工作池函数示例及添加std::atomic<bool>后的问题。
  • 竞态条件产生原因及后果。
  • 正确解决办法是在析构函数中获取互斥锁。

重要细节

  • 代码中std::unique_lock<std::mutex>用于保护共享资源。
  • 原子变量std::atomic<bool>虽能修复 ThreadSanitizer 报告但不能解决竞态。
  • wait(pred)的等效循环结构。
  • 注意notify_all可在作用域外调用及可能的效率损失。
阅读 9
0 条评论