c++多线程基础三 –同步并发

1 条件变量

1.1 condition_variable

std::condition_variable实际上是一个类,是一个和条件相关的类;

  1. condition_variable成员函数:
    condition_variable成员函数
    结合std::unique_lock<std::mutex> 使用

  2. 使用规则:
    使用规则

  3. wait 使用

    void wait( std::unique_lock<std::mutex>& lock );   (1)    
    --------------------------------------------------------
    template< class Predicate >                        (2)
    void wait( std::unique_lock<std::mutex>& lock, Predicate pred );
    
    • (1) 调用:相当于 (2)的第二个参数为false,wait()将解锁互斥量,并阻塞到本行;
    • (2) 调用:第二个参数为true,wait()直接返回并继续执行。
  4. notify_one唤醒线程

    • wait()不断尝试获取互斥量锁,如果获取不到那么流程就卡在wait()这里等待获取,如果获取到了,那么wait()就继续执行,获取到了锁
    • 如果wait有第二个参数就判断这个lambda表达式。
      a): 如果表达式为false,那wait又对互斥量解锁,然后又休眠,等待再次被notify_one()唤醒
      b): 如果lambda表达式为true,则wait返回,流程可以继续执行(此时互斥量已被锁住)。
    • 如果wait没有第二个参数,则wait返回,流程走下去。

注意:wait和wait_for 会先判断这个lambda表达式,如果表达式返回结果为true,则直接唤醒,流程继续执行,不会wait线程。

  1. 条件变量注意事项

    • 条件变量虚假唤醒

      whlie (tasks.empty()) {
          pthread_cond_wait(&mycv, &mymutex);
      }
      

      为什么不写成这样?

      if (tasks.empty()) {
        pthread_cond_wait(&mycv, &mymutex);
      }
      

      因为操作系统唤醒 pthread_cond_wait 时, tasks.empty() 可能仍为true,即操作系统可能再某些情况下唤醒条件变量,也就是说存在没有其他线程向条件变量发送信号,但等待此条件变量的线程有可能醒来的情形。

      使用lambda表达式来解决,不用while循环,

      cv.wait(lck, [] {return !tasks.empty();});
      
    • 条件变量信号丢失
      如果一个条件变量信号在产生时(调用pthread_cond_signal 或者 pthread_cond_broadcast) ,没有相关线程调用 pthread_cond_wait 捕获该信号,该信号就会永久丢失,再次调用pthread_cond_wait会导致永久阻塞。要注意这种情况,建议使用sem 信号

原文链接: https://www.cnblogs.com/lihaihui1991/p/14284584.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    c++多线程基础三 --同步并发

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/400353

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年4月14日 下午2:06
下一篇 2023年4月14日 下午2:06

相关推荐