pthread_cond_wait不会解锁互斥锁

pthread_cond_wait does not unlock the mutex

本文关键字:解锁 cond wait pthread      更新时间:2023-10-16

首先,我的问题有所不同。

在我的场景中,有一个等待线程,它等待条件变量。信令线程发出信号条件变量。

我的代码是

//Wating thread
//Lock the mutex_
//mutex_ is of pthread_mutex_t  and is initialized.
result = pthread_mutex_lock(&mutex_);
assert(result == 0);
do {
    //Wait on condition variable cvar_
    //cva_ is of pthread_cond_t  and is initialized.
    result = pthread_cond_wait(&cvar_, &mutex_);  //POINT 1
}while(result == 0 && !state_);
//Unlock the mutex_.
result = pthread_mutex_unlock(&mutex_);
//signalling thread
result = pthread_mutex_lock(&mutex_); //POINT 2
assert(result == 0);
state_ = 1;
result = pthread_mutex_unlock(&mutex_);
assert(result == 0);
//signals the condition variable.
pthread_cond_signal(&cvar_);

我的操作系统是Mac OS X 10.8,但最低目标是10.6
这运行良好,几乎在所有情况下都没有任何问题,除了一种情况。

在特定情况下,我注意到在 POINT 1 之后pthread_cond_wait ,mutex_进入等待状态时不会解锁。我确认了这一点 pthread_mutex_trylock 在这种情况下返回 EBUS。因此,信令线程进入等待状态,最终导致死锁。

我想知道在什么条件下,pthread_cond_wait不会解锁传递给它的互斥锁。这个问题的原因是什么?

正如@KenThomases指出的:你的问题是你错过了信号,而不是信号没有被发送。 信令线程在等待线程调用pthread_cond_wait()之前调用pthread_cond_signal()。 只有在测试了当前未满足要查找的不变量,才应调用pthread_cond_wait()

while (!state_) {
  result = pthread_cond_wait(&cvar_, &mutex_);
  if (result == EINVAL) ... // error handling
}

有时可以提供帮助的另一件事是将信令线程的调用放在关键部分内pthread_cond_signal()。 这不是解决您的问题所必需的,但可以使程序更容易推理,因为您知道在您向他们发出信号时没有其他人持有互斥锁:

// signalling thread
...
result = pthread_mutex_lock(&mutex_);
...
state_ = 1;
//signals the condition variable.
pthread_cond_signal(&cvar_);
result = pthread_mutex_unlock(&mutex_);
...

在阅读了pthread_setcancelstate之后,我发现pthread_cond_wait是线程的取消点。如果为线程启用了取消并延迟,则取消点将测试取消。如果任何取消挂起,线程将退出。

因此,就我而言,线程退出使mutex_被锁定。因此,信号线程块。

但还有一个疑问。所有线程都是使用 Thread 类从同一函数创建的。为什么只有这个线程有这样的取消行为?