虚假唤醒(spurious wankeups)

典型案例:在wait端必须用while来等待条件变量而不能用if。

// wait端
pthread_mutex_lock(mtx);
while(deque.empty())
    pthread_cond_wait(...);
deque.pop_front();
pthread_mutex_unlock(mtx);
 
// signal端
pthread_mutex_lock(mtx);
deque.push_back(x);
pthread_cond_signal(...);
pthread_mutex_unlock(mtx);

因为:

  1. 在Linux2.6以前,如果有多个消费者,这些消费者可能在同一时间被唤醒,但是只有一个可以往下执行,后面的消费者相当于被虚假唤醒了。实际上现在的Linux内核不会出现惊群效应了,只有一个进程被唤醒。
  2. This means that when you wait on a condition variable,the wait may (occasionally) return when no thread specifically broadcast or signaled that condition variable.Spurious wakeups may sound strange, but on some multiprocessor systems, making condition wakeup completely predictable might substantially slow all condition variable operations. The race conditions that cause spurious wakeups should be considered rare.意思就是,即使没有线程broadcast或者signal条件变量,wait也可能偶尔返回。
comments powered by Disqus