11

Linux Programming Interface book 有一段代码(生产者/消费者)来展示条件变量的工作原理:

static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

static int avail = 0;

while (TRUE) {
    s = pthread_mutex_lock(&mtx);

    while (avail == 0) {   /* Wait for something to consume */
       s = pthread_cond_wait(&cond, &mtx);
    }

    while (avail > 0) {   /* Consume all available units */ 
        avail--;
    }

    s = pthread_mutex_unlock(&mtx);
}

为什么我们使用pthread_mutex_lockin while?为什么我们不在一个中使用它if

4

1 回答 1

13

因为pthread_cond_signal()被允许唤醒多个等待条件变量的线程。因此,一旦你醒来,你必须仔细检查条件,因为其他线程可能已经在你之前醒来并改变了它。

如果您知道只有一个线程在等待,并且您确定将来没有人会修改程序中其他地方的代码以添加另一个线程等待,那么您可以使用if. 但你永远不知道这一点,所以总是使用while.

[更新]

正如 ninjalj 在评论中指出的那样,由于没有提及“虚假唤醒”,我的回答是不完整的。例如,POSIX 标准明确表明,如果等待线程接收到信号(例如通过 kill()),即使没有其他线程向条件变量发出信号,pthread_cond_wait() 也可以返回 0。关于是否可以无缘无故唤醒等待线程的标准是模棱两可的(在我看来)......但底线是:总是使用while,而不是if

于 2011-06-01T19:17:54.513 回答