1 条件变量
1.1 condition_variable
std::condition_variable实际上是一个类,是一个和条件相关的类;
-
condition_variable成员函数:
结合std::unique_lock<std::mutex> 使用 -
使用规则:
-
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()直接返回并继续执行。
-
notify_one唤醒线程
- wait()不断尝试获取互斥量锁,如果获取不到那么流程就卡在wait()这里等待获取,如果获取到了,那么wait()就继续执行,获取到了锁
- 如果wait有第二个参数就判断这个lambda表达式。
a): 如果表达式为false,那wait又对互斥量解锁,然后又休眠,等待再次被notify_one()唤醒
b): 如果lambda表达式为true,则wait返回,流程可以继续执行(此时互斥量已被锁住)。 - 如果wait没有第二个参数,则wait返回,流程走下去。
注意
:wait和wait_for 会先判断这个lambda表达式,如果表达式返回结果为true,则直接唤醒,流程继续执行,不会wait线程。
-
条件变量注意事项
-
条件变量虚假唤醒
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大佬
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/400353
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!