【问题标题】:Pthread mutex assertion errorPthread互斥断言错误
【发布时间】:2010-11-09 11:55:07
【问题描述】:

我在基于 linux (arm) 的通信应用程序中在不可预知的时间遇到​​以下错误:

pthread_mutex_lock.c:82: __pthread_mutex_lock: Assertion `mutex->__data.__owner == 0' failed.

Google 找到了很多关于该错误的引用,但似乎与我的情况相关的信息很少。我想知道是否有人可以给我一些有关如何解决此错误的想法。有谁知道这个断言的常见原因?

提前致谢。

【问题讨论】:

  • 在排除了所有其他可能性后,我决定投资一些 RTFM。看来我一直在以不受官方支持的方式使用互斥锁。当一个线程在等待一些外部刺激时,它会等待它的互斥体。当互斥锁被释放时,线程恢复活力,总是来自另一个线程。所以释放线程从不互斥锁的所有者。我更改了实现以使用条件变量。我还不知道这是否是我烦恼的原因。多年来,我一直(错误地)以这种方式使用互斥锁,直到现在都没有遇到任何问题。
  • 难道pthread_mutexes(和一般的互斥锁)没有记录,因此它们必须由锁定它们的同一线程解锁?它碰巧在其他平台上工作的事实是特定于实现而不是可移植的。
  • 我认为这就是我在上面的评论中所说的。我的实现误用了互斥锁,所以我对其进行了更改以正确使用条件变量。剩下的就是确认这实际上是断断续续的断言背后的原因。
  • 当我的互斥锁未正确初始化时,有时我会遇到同样的错误 --> 使用 pthread_mutex_init

标签: linux pthreads mutex assert glibc


【解决方案1】:

如果您使用 C++ 和 std::unique_lock,请查看以下答案:https://stackoverflow.com/a/9240466/9057530

【讨论】:

  • @mark 你是对的。我改变了答案。
  • @yyFred 你这里还有一点错别字。我想它必须是unique 而不是unqiue。只是说。祝你有美好的一天!
【解决方案2】:

我刚刚完成了这一任务,并认为它可能对其他人有所帮助。 就我而言,问题发生在一个非常简单的方法中,该方法锁定了互斥锁,检查了一个共享变量,然后返回。 该方法是对创建工作线程的基类的覆盖。

这个实例的问题是基类在构造函数中创建线程。然后线程开始执行并调用该方法的派生类实现。不幸的是,派生类尚未完成构造,并且派生类中的互斥体作为互斥体所有者具有未初始化的数据。这使它看起来像实际上被锁定了,而实际上并没有。

解决方案非常简单。向名为 StartThread() 的基类添加一个受保护的方法。这需要在派生类构造函数中调用,而不是从基类中调用。

【讨论】:

    【解决方案3】:

    TLDR:确保您没有锁定已销毁/尚未初始化的互斥锁。

    虽然 OP 有他的答案,但我想我会分享我的问题,以防其他人遇到与我相同的问题。

    请注意,断言在__pthread_mutex_lock 中,而不是在解锁中。对我来说,这表明大多数其他遇到此问题的人并没有在与锁定它的线程不同的线程中解锁互斥锁;他们只是锁定了一个已被破坏的互斥体。

    对我来说,我有一个类(我们称之为Foo),它向其他类(我们称之为Bar)注册了一个静态回调函数。回调传递了对Foo 的引用,并且偶尔会锁定/解锁作为Foo 成员的互斥锁。

    此问题发生在Foo 实例被销毁而Bar 实例仍在使用回调之后。回调传递了一个对不再存在的对象的引用,因此在垃圾内存上调用 __pthread_mutex_lock。

    注意,我使用的是 C++11 的 std::mutexstd::lock_guard<std::mutex>,但是,由于我使用的是 Linux,所以问题完全一样。

    【讨论】:

    • 补充一点,我在两次解锁同一个锁时发生了这种情况。断言错误发生在我下次尝试获取锁时,这使得它更难找到。
    【解决方案4】:

    在 /etc/odbcinst.ini 文件中添加 Threading=0 解决了这个问题

    【讨论】:

      【解决方案5】:

      我遇到了同样的问题

      在我的情况下,在线程内部,我将 vertica db 与 odbc 连接 将以下设置添加到 /etc/odbcinst.ini 解决了我的问题。到目前为止没有得到异常。

      [ODBC]
      Threading = 1
      

      感谢:hynek

      【讨论】:

        【解决方案6】:

        我遇到了同样的问题,谷歌把我送到了这里。我的程序的问题是,在某些情况下,我没有在锁定互斥体之前对其进行初始化。

        虽然接受的答案中的陈述是合法的,但我认为这不是这个断言失败的原因。因为在pthread_mutex_lock上报错(并且没有解锁)。

        此外,与往常一样,错误更有可能出在程序员的源代码中,而不是编译器中。

        【讨论】:

          【解决方案7】:

          连续 4 天坚如磐石。我宣布这一点的胜利。答案是“愚蠢的用户错误”(参见上面的 cmets)。互斥锁只能由锁定它的线程解锁。感谢您对我的包容。

          【讨论】:

          • 你的解决方案只适用于解锁,对吧?我在尝试锁定它时遇到了同样的错误。
          【解决方案8】:

          我在 Google 上进行的快速搜索经常将此归咎于编译器优化错误。一个不错的总结是here。可能值得查看汇编输出以查看 gcc 是否生成了正确的代码。

          要么这样,要么你设法踩到 pthread 库使用的内存......这类问题很难找到。

          【讨论】:

          • 我一直在编译器错误优化路径下,在这种情况下这似乎不是问题:assert (mutex->__data.__owner == 0); 154:e5953008 ldr r3,[r5,#8] 158:e3530000 cmp r3,#0; 0x0 15c: 1a0001a0 bne 7e4 <__pthread_mutex_lock>
          猜你喜欢
          • 2017-11-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-06-06
          • 1970-01-01
          相关资源
          最近更新 更多