首先,我的问题不同。
在我的场景中,有一个等待线程,它等待条件变量。信令线程表示条件变量。
我的代码是
//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
除了一个外,几乎在所有情况下都没有任何问题,运行正常。
在特定情况下,我注意到在{1}}的POINT 1之后,当进入等待状态时,mutex_没有被解锁。这由pthread_cond_wait
确认,在这种情况下返回EBUSY。由于这个原因,信令线程进入等待状态并最终导致死锁。
我想知道在什么条件下,pthread_mutex_trylock
无法解锁传递给它的互斥锁。这个问题的原因是什么?
答案 0 :(得分:1)
正如@KenThomases指出的那样:你的问题是你错过了信号,而不是信号没有被发送。 等待线程调用pthread_cond_signal()
之前,信令线程正在调用pthread_cond_wait()
。 {/ 1}}只应在之后调用,您已经测试过当前不符合您要查找的不变量:
pthread_cond_wait()
有时可以帮助的另一件事是将信令线程的调用放在临界区内的while (!state_) {
result = pthread_cond_wait(&cvar_, &mutex_);
if (result == EINVAL) ... // error handling
}
。这不是解决问题所必需的,但是可以使程序更容易推理,因为您知道在您发出信号时没有其他人持有互斥锁:
pthread_cond_signal()
答案 1 :(得分:0)
在阅读pthread_setcancelstate后,我发现pthread_cond_wait
是该帖子的取消点。如果为线程启用了取消并且延迟,则取消点将测试取消。如果有任何取消待处理,则线程将退出。
因此,在我的情况下,线程退出而使mutex_锁定。因此,信令线程块。
但还有一个疑问。所有线程都是使用Thread类从同一个函数创建的。为什么只有这个线程有这种取消行为?