pthread_cond_wait 无限期地阻塞(休眠)直到 pthread_cond_signal 被 C 中的另一个线程调用?

pthread_cond_wait blocks(sleeps) indefinitely until pthread_cond_signal is called by another thread in C?

如果一个线程:A 在pthread_cond_wait 中阻塞了一个条件, 我们的线程 A 会无限期地等待 pthread_cond_signal 在另一个线程中被调用吗? 或者,即使条件以某种方式变为真(工作负载> MAXLOAD),它也会被唤醒,而无需使用 pthread_cond_wait.

发出信号

线程 A:

while(1) {
    pthread_mutex_lock( &recoveryMutex );  
    while( workload < MAXLOAD ) {                               
        pthread_cond_wait(&recoveryCond, &recoveryMutex );      
    }
    /* Recovery Code */
    /* Recovery Code */
    /* Recovery Code */        
    pthread_mutex_unlock(&recoveryMutex);
}

我相信你需要 pthread_cond_signal() or pthread_cond_broadcast()

三个有用的链接:

The POSIX pthread_cond_wait() documentation 很好地解释了 pthread_cond_wait() 的工作原理:

Condition Wait Semantics

It is important to note that when pthread_cond_wait() and pthread_cond_timedwait() return without error, the associated predicate may still be false. Similarly, when pthread_cond_timedwait() returns with the timeout error, the associated predicate may be true due to an unavoidable race between the expiration of the timeout and the predicate state change.

The application needs to recheck the predicate on any return because it cannot be sure there is another thread waiting on the thread to handle the signal, and if there is not then the signal is lost. The burden is on the application to check the predicate.

Some implementations, particularly on a multi-processor, may sometimes cause multiple threads to wake up when the condition variable is signaled simultaneously on different processors.

In general, whenever a condition wait returns, the thread has to re-evaluate the predicate associated with the condition wait to determine whether it can safely proceed, should wait again, or should declare a timeout. A return from the wait does not imply that the associated predicate is either true or false.

It is thus recommended that a condition wait be enclosed in the equivalent of a "while loop" that checks the predicate.

你的线程可以随时被唤醒,所以你需要检查你的( workload < MAXLOAD )。但是更改该条件(通过为 workload 分配新值)不会唤醒阻塞在 pthread_cond_wait() 中的线程。

您需要调用 pthread_cond_signal() 以保证唤醒。

但您还需要处理 "spurious wakeups"。每 the POSIX pthread_cond_signal() documentation:

POSIX.1-2017 explicitly documents that spurious wakeups may occur.

简而言之,是的,它block/sleeps无限期地直到你发出信号。

pthread_cond_wait 可能 出于任何原因唤醒 "spuriously"(这通常与条件变为真没有任何关系;机械上没有合理的方式一个关系可能会成为),但在 pthread_cond_signalpthread_cond_broadcast 被调用之前没有合同被唤醒。每当您对状态进行一些更改可能导致谓词的真值发生更改时,您都需要调用这些函数之一。