【问题标题】:pthread_mutex_lock_full assertion failed errorpthread_mutex_lock_full 断言失败错误
【发布时间】:2021-10-11 22:18:21
【问题描述】:

我一直在编写一个 pthread 应用程序。应用程序具有由父线程跨线程共享的互斥锁。由于某种原因,它会引发以下错误:

../nptl/pthread_mutex_lock.c:428: __pthread_mutex_lock_full: Assertion `e != ESRCH || !robust' failed.

该应用程序用于使用基于packet_mmap 的方法捕获高速网络流量,其中有多个线程,每个线程都与一个套接字相关联。我不确定为什么会这样。它发生在测试期间,我无法一直重现该错误。我用谷歌搜索了很多,但我无法知道原因。感谢您的帮助。

错误的原因是由于文件读取。当文件读取的行被注释时,错误不会发生。它发生在这一行:

fread(this->bit_array, sizeof(int), this->m , fp);

其中bit_array 是一个动态分配的整数数组,m 是数组的大小。

谢谢。

【问题讨论】:

  • 您是使用应用程序还是编程应用程序?因为如果你只是一个用户,就联系开发者吧。
  • ESRCH 是“没有这样的进程”,所以可能持有互斥锁的线程死了。

标签: c++ c pthreads mutex


【解决方案1】:

在 GLIBC 2.31 中,您正在运行 pthread_mutex_lock() 的以下源代码:

    oldval = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
                              newval, 0);

    if (oldval != 0)
      {
        /* The mutex is locked.  The kernel will now take care of
           everything.  */
        int private = (robust
               ? PTHREAD_ROBUST_MUTEX_PSHARED (mutex)
               : PTHREAD_MUTEX_PSHARED (mutex));
        int e = futex_lock_pi ((unsigned int *) &mutex->__data.__lock,
                   NULL, private);
        if (e == ESRCH || e == EDEADLK)
          {
        assert (e != EDEADLK
            || (kind != PTHREAD_MUTEX_ERRORCHECK_NP
                && kind != PTHREAD_MUTEX_RECURSIVE_NP));
        /* ESRCH can happen only for non-robust PI mutexes where
           the owner of the lock died.  */
        assert (e != ESRCH || !robust);

        /* Delay the thread indefinitely.  */
        while (1)
          lll_timedwait (&(int){0}, 0, 0 /* ignored */, NULL,
                 private);
          }

        oldval = mutex->__data.__lock;

        assert (robust || (oldval & FUTEX_OWNER_DIED) == 0);
      }

在上面的代码中,互斥锁的当前值是原子读取的,它看起来不同于0 意味着互斥锁被锁定。 然后,断言被触发,因为互斥锁的所有者死亡并且互斥锁不是一个健壮的(意味着互斥锁没有在所有者线程结束时自动释放)。

如果您可以修改源代码,您可能需要在互斥锁(pthread_mutexattr_setrobust())中添加“robust”属性,以便在所有者死亡时系统自动释放它。但它很容易出错,因为相应的代码关键部分可能还没有达到理智点,因此可能会留下一些未完成的工作......

因此,最好在未解锁互斥锁的情况下找出线程可能死亡的原因。要么是错误,要么是你忘记释放终止分支中的互斥锁。

【讨论】:

    【解决方案2】:

    this copy of GLIBC's pthread_mutex_lock.c:

        /* ESRCH can happen only for non-robust PI mutexes where
           the owner of the lock died.  */
        assert (INTERNAL_SYSCALL_ERRNO (e, __err) != ESRCH || !robust);
    

    您的一个线程/进程在没有释放其所有锁定资源的情况下结束,或者您正在使用 pthread_cancel()/kill() 并在线程或进程运行时杀死它们。

    【讨论】:

      猜你喜欢
      • 2012-11-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-22
      • 2017-07-14
      • 1970-01-01
      相关资源
      最近更新 更多