互斥锁和条件变量
1.条件变量和mutex到底有什么区别?都是在没有拿锁的情况下阻塞,拿到锁了解除阻塞。那为什么还要用条件变量呢?
2.pthread_cond_broadcast和pthread_cond_signal。既然阻塞的线程被唤醒了之后第一件事就是拿锁,那么即使是broadcast,也会竞争锁,导致只有一个线程能继续,那么signal和broadcast有什么区别吗?
3、在多核处理器下,pthread_cond_signal可能会激活多于一个线程(阻塞在条件变量上的线程)。
结果是,当一个线程调用pthread_cond_signal()后,多个调用pthread_cond_wait()或pthread_cond_timedwait()的线程返回。这种效应成为”虚假唤醒”(spurious wakeup) 。
虽然虚假唤醒在pthread_cond_wait函数中可以解决,为了发生概率很低的情况而降低边缘条件(fringe condition)效率是不值得的,纠正这个问题会降低对所有基于它的所有更高级的同步操作的并发度。所以pthread_cond_wait的实现上没有去解决它。
所以通常的标准解决办法是这样的:
将条件的判断从if 改为while
pthread_cond_wait中的while()不仅仅在等待条件变量前检查条件变量,实际上在等待条件变量后也检查条件变量。
这样对condition进行多做一次判断,即可避免“虚假唤醒”.
这就是为什么在pthread_cond_wait()前要加一个while循环来判断条件是否为假的原因。
有意思的是这个问题也存在几乎所有地方,包括: linux 条件等待的描述, POSIX Threads的描述, window API(condition variable), java等等。