0

首先,我的问题是不同的。

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

我的代码是

//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返回 EBUSY 确认了这一点。因此,信号线程进入等待状态并最终导致死锁。

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

4

2 回答 2

1

As @KenThomases pointed out: your problem is that you are missing the signal, not that the signal isn't getting sent. The signalling thread is calling pthread_cond_signal() before the waiting thread calls pthread_cond_wait(). pthread_cond_wait() should only be called after you've tested that the invariants you are looking for aren't currently met:

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

The other thing that can help sometimes is to put the signalling thread's call to pthread_cond_signal() inside the critical section. This isn't necessary to fix your problem, but can make the program easier to reason about because you know that no-one else is holding the mutex at the time you signal them:

// signalling thread
...
result = pthread_mutex_lock(&mutex_);
...
state_ = 1;
//signals the condition variable.
pthread_cond_signal(&cvar_);
result = pthread_mutex_unlock(&mutex_);
...
于 2013-09-26T01:34:48.697 回答
0

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

因此,在我的情况下,线程退出而 mutex_ 被锁定。因此发出信号线程块。

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

于 2013-09-28T04:31:06.967 回答