我的程序似乎有一个死锁问题。
基本上,我有一个如下所示的类:
class Foo {
public:
Foo();
void bar();
private:
void monitor();
bool condition_;
pthread_t monitor_;
pthread_mutex_t mutex_;
pthread_cond_t cv_;
};在Foo的构造函数中,我在一个单独的线程中调用monitor() (即monitor_)。此monitor()函数执行以下操作:
pthread_mutex_lock(&mutex_);
while (true) {
while (!condition_) {
pthread_cond_wait(&cv_, &mutex_);
}
// do something
// and then setting condition_ to false
condition_ = false;
}
pthread_mutex_unlock(&mutex_);bar()函数是Foo的唯一公共接口(不包括ctor和dtor)。它还需要在执行过程中获取互斥锁。我的症状是bar()永远无法获得mutex_。看起来pthread_cond_wait()没有像它应该做的那样释放互斥锁。如果我禁用了监视器线程(因此没有竞争条件),那么bar()就可以运行到完成,没有任何问题。
当然,上面的代码是我真实代码的精简版本。实际上,我认为这段代码中没有逻辑错误,我正确地使用了pthread。我怀疑是否有任何其他原因造成这种死锁的情况。有没有人能给出一个线索?谢谢!
发布于 2011-08-03 10:59:11
我将查看您的构造函数和bar()函数,如果您无意中复制了一个有问题的对象,也可能会这样做。我已经复制了您提供的类,以及下面我对其馀部分如何操作的假设。下面的程序每秒都会被唤醒,并向线程发出信号。
#include <pthread.h>
#include <iostream>
class Foo {
public:
Foo() {
condition_ = false;
pthread_mutex_init(&mutex_, NULL);
pthread_cond_init(&cv_, NULL);
pthread_create(&monitor_, NULL,
startFunc, this);
}
void bar() {
pthread_mutex_lock(&mutex_);
std::cout << "BAR" << std::endl;
condition_ = true;
pthread_cond_signal(&cv_);
pthread_mutex_unlock(&mutex_);
}
private:
Foo(const Foo&) {};
Foo& operator=(const Foo&) { return *this; };
static void* startFunc(void* r) {
Foo* f = static_cast<Foo*>(r);
f->monitor();
return NULL;
}
void monitor() {
pthread_mutex_lock(&mutex_);
while (true) {
while (!condition_) {
pthread_cond_wait(&cv_, &mutex_);
}
// do something
// and then setting condition_ to false
std::cout << "FOO" << std::endl;
condition_ = false;
}
pthread_mutex_unlock(&mutex_);
}
bool condition_;
pthread_t monitor_;
pthread_mutex_t mutex_;
pthread_cond_t cv_;
};
int main() {
struct timespec tm = {1,0};
Foo f;
while(true) {
f.bar();
nanosleep(&tm, NULL);
}
}发布于 2011-08-03 10:40:01
我敢打赌,它在这里失败了:
while (!condition_) {
pthread_cond_wait(&cv_, &mutex_);
}假设条件为false。您进入while循环,在第一次运行中一切正常,即解锁互斥锁并等待决策变量。会不会发生条件变量改变而布尔条件不变的情况?在这种情况下,您将使用未初始化的互斥锁进入pthread_cond_wait,并且可能会发生未定义的行为...我想如果您也显示bar()方法会有所帮助。
另一种猜测是线程优先级。也许可以插入一个yield,让线程有更好的切换机会。
发布于 2013-09-07 01:13:05
如果您再次遇到这种情况,我遇到了一个非常类似的情况,我遇到了一个死锁,我期望cond_wait释放互斥锁,以便其他线程可以锁定互斥锁。
我的问题是我已经将互斥锁设置为递归的(使用settype->PTHREAD_ recursive _NP),并且在cond_wait调用之前错误地锁定了互斥锁两次。由于cond_wait只解锁了它一次,互斥锁仍然是锁定的。显而易见的解决方法是只锁定它一次。此外,作为一个教训,我不会使用递归互斥设置,除非我真的需要这样做。
https://stackoverflow.com/questions/6921013
复制相似问题