首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Pthread_cond_wait()没有释放互斥锁的可能原因?

Pthread_cond_wait()没有释放互斥锁的可能原因?
EN

Stack Overflow用户
提问于 2011-08-03 10:28:32
回答 3查看 1.4K关注 0票数 0

我的程序似乎有一个死锁问题。

基本上,我有一个如下所示的类:

代码语言:javascript
复制
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()函数执行以下操作:

代码语言:javascript
复制
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。我怀疑是否有任何其他原因造成这种死锁的情况。有没有人能给出一个线索?谢谢!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-08-03 10:59:11

我将查看您的构造函数和bar()函数,如果您无意中复制了一个有问题的对象,也可能会这样做。我已经复制了您提供的类,以及下面我对其馀部分如何操作的假设。下面的程序每秒都会被唤醒,并向线程发出信号。

代码语言:javascript
复制
#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);
  }

}
票数 0
EN

Stack Overflow用户

发布于 2011-08-03 10:40:01

我敢打赌,它在这里失败了:

代码语言:javascript
复制
while (!condition_) {
    pthread_cond_wait(&cv_, &mutex_);
}

假设条件为false。您进入while循环,在第一次运行中一切正常,即解锁互斥锁并等待决策变量。会不会发生条件变量改变而布尔条件不变的情况?在这种情况下,您将使用未初始化的互斥锁进入pthread_cond_wait,并且可能会发生未定义的行为...我想如果您也显示bar()方法会有所帮助。

另一种猜测是线程优先级。也许可以插入一个yield,让线程有更好的切换机会。

票数 0
EN

Stack Overflow用户

发布于 2013-09-07 01:13:05

如果您再次遇到这种情况,我遇到了一个非常类似的情况,我遇到了一个死锁,我期望cond_wait释放互斥锁,以便其他线程可以锁定互斥锁。

我的问题是我已经将互斥锁设置为递归的(使用settype->PTHREAD_ recursive _NP),并且在cond_wait调用之前错误地锁定了互斥锁两次。由于cond_wait只解锁了它一次,互斥锁仍然是锁定的。显而易见的解决方法是只锁定它一次。此外,作为一个教训,我不会使用递归互斥设置,除非我真的需要这样做。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6921013

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档