http://www.zyfforlinux.cc/2015/04/11/linux%E5%A4%9A%E7%BA%BF%E7%A8%8B%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%AB%AF%E7%BC%96%E7%A8%8B-%E7%AC%AC%E4%BA%8C%E7%AB%A0/
2.2条件变量
只有一种正确做法,几乎不可能出错
对于wait端:
- 必须与mutex一起使用,该布尔表达式的读写需受此mutex保护
- 在mutex已上锁的时候才能调用wait()
- 把判断布尔条件和wait()放到while循环中
int dequeue()
{
MutexLockGuard lock(mutex); //1
while(queue.empty()) //3
{
//放在while循环是防止被信号中断,造成虚假唤醒
cond.wait();//2
}
assert(!queue.empty());
int top = queue.front();
queue.pop_front();
return top;
}
对于signal/broadcast端:
- 不一定要在mutex已上锁的情况下调用signal
- 在signal前一般要修改布尔表达式
- 修改布尔表达式一般需要使用mutex进行保护
- 注意区分signal和broadcast,后者通常用于表明状态变化,前置表示资源可用。
void enqueue(int x)
{
MutexLockGuard lock(mutex);
queue.push_back(x);
cond.notify();//可以放在临界区之外
}
2.6 sleep(3)不是同步原语
sleep()/usleep()/nanosleep()只能出现在测试代码中。sleep不具备memory barrier语义.不能保证
内存的可见性.这些都是在用户态做轮询这是低效的。如果需要等待一段时间去执行某个代码,可以注册
一个timer,然后在timer的回调函数中干活。
浙公网安备 33010602011771号