pthread_mutex_lock锁定,但未设置所有者

pthread_mutex_lock锁定,但未设置所有者,c,pthreads,C,Pthreads,我已经做了几天了- 作为背景,我正在研究一个单线程的C程序,并使其成为多线程的。我最近发现了一个新的死锁案例,但当我查看gdb中的互斥时,我看到了这一点 __锁=2,但所有者=0 这不是递归互斥。有人见过这个吗?我正在处理的程序是一个守护进程,这种情况只有在以高吞吐率执行超过20分钟(大约)然后释放负载后才会发生。如果你有什么想法,我将不胜感激 编辑-我忘了提到我的所有其他线程在这个时候都是空闲的 干杯这是意料之中的事。普通(非递归、非错误检查)互斥体不需要存储其所有者,跳过查找调用方线程id的

我已经做了几天了-

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

__锁=2,但所有者=0

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

编辑-我忘了提到我的所有其他线程在这个时候都是空闲的


干杯

这是意料之中的事。普通(非递归、非错误检查)互斥体不需要存储其所有者,跳过查找调用方线程id的步骤可以节省一些时间。(这在x86上没有什么区别,但在诸如具有损坏ABI的MIPS这样的平台上可能会有很大的区别,在这些平台上没有线程寄存器,获取线程id会导致内核空间出错。)


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

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

我刚刚修复了我遇到的问题-堆栈损坏导致了
互斥锁。\uu数据。\uu锁
值被设置为某个可笑的数字(40亿ish)在尝试调用
pthread\u mutex\u lock
之前。在执行锁操作之前,看看是否可以设置断点,或者打印
\u lock
值的调试信息,我敢打赌它在死锁发生之前是无效的。

一些源代码,任何建立上下文的源代码都会非常有用。@不,我经常在valgrind中运行它来检查事情是否正常,但我会再运行一次,看看我是否犯了一些新错误。@Josh-代码总共超过200k行。守护进程通过将任务按顺序放入队列并定期检查它们是否准备好执行来跟踪定时任务,因此这个对象及其mutex用于检查它是否准备好执行。如果准备好了,它将从队列中删除并调用函数。除此之外,访问它只是为了在按顺序插入其他对象时检查其时间。如果您的互斥锁没有正确初始化,您可能会得到这样的结果。@不-这是我的第一个想法,但是互斥锁总是初始化的(它只在一个函数中创建)。我不同意这种说法——这是不正常的。我过去跟踪死锁的方法是检查互斥锁的所有者,然后检查。我应该提到的另一个细节是,此时所有其他线程都处于空闲状态(我将编辑我的帖子)。另外,非递归互斥锁如何具有2的锁?我的理解是,只有递归互斥锁的锁值才能大于1。这都是特定于实现的,但我怀疑
lock
字段是否是引用计数。几乎可以肯定,这只是原子交换锁定字段。我怀疑0表示解锁,1表示锁定和uncontend,2表示与潜在的侍者锁定。如果有疑问,请阅读源代码。@dbeer:R..实际上是对的,普通互斥锁不保存所有者,IIRC保存在递归互斥锁和错误检查互斥锁上,我将尝试将其设为递归互斥锁,看看我得到了什么。嗯,我想说它有助于诊断/调试,所以不能完全使用字母S。