在基于 linux(arm)的通信应用程序中,我在不可预知的时间遇到以下错误:
pthread_mutex_lock.c:82: __pthread_mutex_lock: Assertion `mutex->__data.__owner == 0' failed.
谷歌出现了很多关于该错误的引用,但似乎与我的情况相关的信息很少。我想知道是否有人可以给我一些有关如何解决此错误的想法。有谁知道这个断言的共同原因?
提前致谢。
连续4天坚如磐石。我宣布这一点的胜利。答案是“愚蠢的用户错误”(见上面的评论)。互斥锁只能由锁定它的线程解锁。谢谢你陪我。
尽管 OP 有他的答案,但我想我会分享我的问题,以防其他人遇到与我相同的问题。
请注意,断言在解锁中__pthread_mutex_lock
而不是在解锁中。对我来说,这表明大多数其他遇到此问题的人并没有在与锁定它的线程不同的线程中解锁互斥锁;他们只是锁定一个已被破坏的互斥锁。
对我来说,我有一个类(我们称之为它Foo
),它向其他类(我们称之为它)注册了一个静态回调函数Bar
。回调被传递了一个引用,Foo
并且偶尔会锁定/解锁一个互斥锁,该互斥锁是Foo
.
此问题发生在Foo
实例被销毁而Bar
实例仍在使用回调之后。回调传递了对不再存在的对象的引用,因此在垃圾内存上调用 __pthread_mutex_lock。
请注意,我使用的是 C++11std::mutex
和std::lock_guard<std::mutex>
,但是,由于我使用的是 Linux,所以问题完全相同。
我遇到了同样的问题,谷歌把我送到了这里。我的程序的问题是,在某些情况下,我没有在锁定互斥锁之前对其进行初始化。
尽管接受的答案中的陈述是合法的,但我认为这不是这个断言失败的原因。因为报错pthread_mutex_lock
(而不是解锁)。
此外,与往常一样,错误更有可能出现在程序员的源代码中,而不是编译器中。
我所做的快速谷歌搜索经常将此归咎于编译器错误优化。一个不错的总结就在这里。可能值得查看汇编输出以查看 gcc 是否生成了正确的代码。
要么,要么你设法踩到 pthread 库使用的内存......这类问题很难找到。
我遇到了同样的问题
在我的情况下,在线程内部,我将 vertica db 与 odbc 添加到 /etc/odbcinst.ini 中,解决了我的问题。到目前为止没有得到异常。
[ODBC]
Threading = 1
归功于:海尼克
我刚刚通过这个努力,并认为它可能会帮助其他人。在我的情况下,问题发生在一个非常简单的方法中,该方法锁定了互斥锁,检查了一个共享变量,然后返回。该方法是创建工作线程的基类的覆盖。
这个实例的问题是基类在构造函数中创建线程。然后线程开始执行并调用该方法的派生类实现。不幸的是,派生类尚未完成构造,并且派生类中的互斥体作为互斥体所有者具有未初始化的数据。这使它看起来好像实际上被锁定了,而实际上它没有被锁定。
解决方案非常简单。向名为 StartThread() 的基类添加一个受保护的方法。这需要在派生类构造函数中调用,而不是从基类中调用。
如果您使用的是 C++ 和std::unique_lock
,请检查以下答案:https ://stackoverflow.com/a/9240466/9057530
在 /etc/odbcinst.ini 文件中添加 Threading=0 解决了这个问题