【问题标题】:Need help to debug mutex dead lock需要帮助调试互斥锁死锁
【发布时间】:2012-03-25 04:01:02
【问题描述】:

我在下面的代码中有一个互斥锁死锁:

CRegistry::CRegistry()
{
    pthread_mutex_init(&_Mutex, NULL);
}

CRegistry::~CRegistry()
{
    pthread_mutex_destroy(&_Mutex);
}

MR_RESULT CRegistry::Register(const REGISTRY_KEY &Id, const REGISTRY_ITEM &Item)
{
    pair<REGISTRY::iterator, bool> Result;

    pthread_mutex_lock(&_Mutex);
    Result = _Registry.insert(pair<REGISTRY_KEY, REGISTRY_ITEM>(Id, Item));
    pthread_mutex_unlock(&_Mutex);

    if (Result.second == true)
        return MR_RESULT_OK;
    else
        return MR_RESULT_ERROR;
}

MR_RESULT CRegistry::UnRegister(const REGISTRY_KEY &Id)
{
    REGISTRY::size_type Result;

    pthread_mutex_lock(&_Mutex);
    Result = _Registry.erase(Id);
    pthread_mutex_unlock(&_Mutex);

    if (Result == 1)
        return MR_RESULT_OK;
    else
        return MR_RESULT_ERROR;
}

_Mutext 是一个类成员,不会在代码中的任何其他地方使用。在某些时候,我可以看到一个线程试图锁定已经锁定的互斥锁。

有实时和非实时线程锁定互斥锁。我知道可能存在优先级反转,但这怎么会导致死锁?

【问题讨论】:

  • 您可以将代码发布到pthread_mutex_lock(&amp;_Mutex); 吗?如果该代码无法正确处理已经到位的锁,我可能会看到死锁。
  • _Registry.insert() 或 _Registry.erase() 是否有可能抛出异常?这将使互斥锁锁定...
  • 为什么所有人都这么喜欢保留标识符?不允许使用以下划线和大写字母开头的标识符。 _Registry_Mutex 保留用于实现。
  • CRegistry 可以复制吗?默认复制构造函数和赋值运算符?是否在任何地方复制?
  • both _Registry_Mutex 类级别的吗? IE。前面都有static关键字?

标签: c++ linux pthreads mutex deadlock


【解决方案1】:

您的代码对我来说似乎非常好。您确定 _Mutex 没有在其他任何地方使用吗?

Valgrind 工具集包括Helgrind,这是一个可以帮助您消除死锁的 pthread 调试器。也许你可以运行它。

【讨论】:

    【解决方案2】:

    你确定有死锁还是只是一个线程被其他更高优先级的线程阻塞了很长时间?

    你有没有考虑过使用

    pthread_mutexattr_setprotocol (&attr, PTHREAD_PRIO_INHERIT)
    

    避免优先级倒置问题?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-10-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-23
      • 1970-01-01
      • 2011-03-03
      相关资源
      最近更新 更多