condition_variable类是一个同步原语,与std::mutex一起使用,用于阻塞一个或多个线程,直到另一个线程修改一个共享变量(条件)并通知condition_variable。condition_variable主要有wait函数和notify_* 函数,wait的作用是等待,notify的作用是通知。Linux环境下的相关接口pthread_cond_*等函数。
当 std::condition_variable对象的某个wait 函数被调用的时候,它使用 std::unique_lock(通过 std::mutex) 来锁住当前线程。当前线程会一直被阻塞,直到另外一个线程在相同的 std::condition_variable 对象上调用了 notification 函数来唤醒当前线程。
wait()还有第二个参数,这个参数接收一个布尔类型的值,当这个布尔类型的值为false的时候线程就会被阻塞在这里,只有当线程被唤醒之后,且第二参数为true才会往下运行。
notify_one()每次只能唤醒一个线程,notify_all()函数的作用就是可以唤醒所有的线程,但是最终能抢夺锁的只有一个线程,或者说有多个线程在wait,但是用notify_one()去唤醒其中一个线程,那么这些线程就出现了去争夺互斥量的情况,最终没有获得锁的控制权的线程就会再次回到阻塞的状态,对于这些没有抢到控制权的过程叫做虚假唤醒。对于虚假唤醒的解决方法就是加一个while()循环,比如:
讯享网
这个就是当线程被唤醒以后,先进行判断,是否可以去操作,如果可以,再去运行下面的代码,否则继续在循环内执行wait函数
上面所说多个线程等待一个唤醒的情况叫做惊群效应。
方法原型:
讯享网
std::condition_variable提供了两种wait()函数。当前线程调用wait()后被阻塞(此时当前线程获得了mutex),直到另外某个线程调用notify_*唤醒了当前线程。
在当前线程被阻塞时,该函数会自动调用lck.unlock()释放锁,使得其他被阻塞在锁竞争上的线程得以继续执行。一旦当前线程获得通知(通常是另外某个线程调用notify_* 唤醒了当前线程),wait()函数也是自动调用lck.lock(),使得lck的状态和wait函数被调用时相同。
在设置了pred的情况下,只有当pred条件为false时调用wait()才会阻塞当前线程,并且在收到其他线程的通知后只有当pred为true时才会被解除阻塞。等效于以下情景。
方法原型:
讯享网
与std::condition_variable::wait()类似,不过wait_for可以指定一个时间段,在当前线程收到通知或者指定的时间rel_time超时之前,该线程都会处于阻塞状态。一旦超时或收到了其他线程的通知,wait_for返回,剩下的处理步骤和wait()类似。
wait_for()的pred表示预测条件,只有当pred条件为false时调用wait()才会阻塞当前线程,并且在收到其他线程的通知后只有当pred为true时才会被解除阻塞。
方法原型:

与wait_for类似,但是wait_until可以指定一个时间点,在当前线程收到通知或者指定的时间点abs_time超时之前,该线程都处于阻塞状态。一旦超时或者收到了其他线程的通知,wait_until返回,剩下的处理步骤和wait()相似
wait_until的重载版本中pred表示wait_until的预测条件,只有当pred条件为false时调用wait()才会阻塞当前线程,并且在收到其他线程的通知后只有当pred为true时才会被解除阻塞
唤醒某个等待(wait)线程。如果当前没有等待线程,则该函数什么也不做,如果同时存在多个等待线程,则唤醒某个线程是不确定的。
唤醒所有等待(wait)线程。如果当前没有等待线程,则什么也不做。
通知其他线程,给定的线程已经全部完成,当调用该函数的线程退出时,所有在cond条件变量上等待的线程都会收到通知
与std::condition_variable类似,只不过std::condition_variable_any的wait函数可以接受任何lockadle参数。而std::condition_variable只能接受std::unique_lock类型的参数,除此意外和std::condition_variable几乎完全一样。
讯享网
运行结果:
参考文章:
https://cloud.tencent.com/developer/article/
https://en.cppreference.com/w/cpp/thread/condition_variable
https://blog.csdn.net/lv0918_qian/article/details/

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/163828.html