概述
本文只是简单的讲了条件变量的含义,着重讲了条件变量的虚假唤醒,最后讲了在使用唤醒的两种方式(signal和broadcast)时的注意事项。
条件变量简单释义
条件变量顾名思义是一个或者多个线程等待某个bool表达式为真,即等待别的线程“唤醒”它。
条件变量的虚假唤醒
例子:
/* In any waiting thread: */ while(!buf->full) wait(&buf->cond, &buf->lock); /* In any other thread: */ if(buf->n >= buf->size){ buf->full = 1; signal(&buf->cond); }
上面的例子中使用while循环来等待条件变量,而不能使用if语句,原因是会存在虚假唤醒(Spurious wakeup)。
虚假唤醒出现的原因是:即使没有线程发信号通知条件变量,线程也可能从其等待状态中唤醒。为了正确,有必要在线程完成等待之后验证条件是否为真。由于虚假唤醒可能会重复发生,因此可以通过等待条件为真时终止的循环来实现。
使用Signal和broadcast注意事项:
1、不一定要在mutex已上锁的情况下调用signal(理论上)。
2、在signal之前一般要修改布尔表达式。
3、修改bool表达式通常要用mutex保护。
4、注意区分signal和broadcast:“broadcast通常用于表明状态变化,signal通常用于表示资源可用”。
参考文献:
https://blog.youkuaiyun.com/amoscykl/article/details/80748420
http://en.wikipedia.org/wiki/Spurious_wakeup
陈硕的《linux多线程服务端编程》