【问题标题】:pthread_mutex_lock locks, but no owner is setpthread_mutex_lock 锁定,但没有设置所有者
【发布时间】:2011-10-05 12:56:44
【问题描述】:

我已经为此工作了几天 -

作为背景,我正在开发一个单线程 C 程序并使其成为多线程。我最近发现了一个新的死锁案例,但是当我查看 gdb 中的互斥锁时,我看到了

__lock=2 还是 __owner=0

这不是递归互斥锁。有人见过这个吗?我正在处理的程序是一个守护程序,这种情况仅在以高吞吐量率执行超过 20 分钟(大约)然后放松负载后才会发生。如果您有任何想法,我将不胜感激。

编辑 - 我没有提到此时我的所有其他线程都处于空闲状态。

干杯

【问题讨论】:

  • 一些来源,任何建立上下文的来源都会非常有帮助。
  • @nos 我在 valgrind 中运行了很多次以检查一切是否正常,但我会再做一些,看看我是否犯了一些新错误。
  • @Josh - 整个代码超过 20 万行。守护进程通过按顺序将 放入队列并定期检查它们是否已准备好执行来跟踪定时任务,因此查看此对象及其互斥锁的唯一时间是检查它是否已准备好执行。如果是,则将其从队列中删除并调用该函数。除此之外,它仅在其他对象按顺序插入时被访问以检查其时间。
  • 如果你的互斥锁没有被正确初始化,你可能会得到这样的结果。
  • @nos - 这是我的第一个想法,但这个互斥锁总是被初始化(它只在一个函数中创建)。

标签: c pthreads


【解决方案1】:

这是意料之中的。一个普通的(非递归的、非错误检查的)互斥体不需要存储它的所有者,并且跳过查找调用者的线程 ID 的步骤可以节省一些时间。 (这在 x86 上几乎没有什么区别,但在 MIPS 等带有损坏 ABI 的平台上可能会有很大的不同,在这些平台上没有线程寄存器并且获取线程 id 会导致内核空间出现故障。)

您看到的死锁几乎可以肯定是由于线程试图锁定它已经持有的互斥锁,或者是两个或多个线程都在等待另一个持有的互斥锁的实际逻辑错误。

【讨论】:

  • 我不同意——这不正常。我过去追踪死锁的方法是检查谁拥有互斥锁,然后检查它。我应该提到的另一个细节是此时所有其他线程都处于空闲状态(我将编辑我的帖子)。此外,非递归互斥锁如何具有 2 个锁?我的理解是只有递归互斥锁的锁值才能> 1。
  • 这都是非常特定于实现的,但我怀疑 lock 字段是引用计数。几乎可以肯定,这只是原子交换换锁领域。我怀疑 0 表示未锁定,1 表示已锁定且未竞争,2 表示已锁定潜在服务员。如有疑问,请阅读来源。
  • @dbeer:R.. 实际上是对的,普通互斥锁不会保存所有者,IIRC 它保存在递归和错误检查互斥锁上,
  • 我将尝试使其成为一个递归互斥体,看看我得到了什么。
  • 好吧,我想说它可以帮助诊断/调试,所以并不是完全没用。
【解决方案2】:

据我所知,这是由于 pthread 库的限制。每当我发现代码的某些部分使用了过多的锁定和解锁并严重强调了该部分的代码时,我就会遇到这种失败。我已经通过重写这些部分来解决它们以最小化它们的锁定,这更容易维护代码(在重新获取可能释放的对象时更少的错误检查)并消除了一些开销。

【讨论】:

    【解决方案3】:

    我刚刚解决了我遇到的问题 - 在尝试调用 pthread_mutex_lock 之前,堆栈损坏导致 mutex.__data.__lock 值设置为某个荒谬的数字(40 亿左右)。看看你是否可以在执行锁定操作之前设置断点,或者在__lock 的值上打印调试信息,我敢打赌它在死锁发生之前是无效的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多