首页 > 解决方案 > 为什么我在同一个线程中使用 pthread_mutex_lock 两次时没有发生核心转储?

问题描述

#include <pthread.h>
#include <iostream>

int main()
{
    pthread_mutex_t mtx;
    pthread_mutex_init(&mtx, NULL);
    pthread_mutex_lock(&mtx);
    pthread_mutex_lock(&mtx);
    return 0;
}

我在 Centos 7 中运行这段代码,我除了有一个核心转储文件,但它没有,程序只是死在命令行中。

我以为 pthread 互斥锁默认是非递归互斥锁,我的程序中只有一个线程,所以当我两次锁定这个互斥锁时,它应该是崩溃的。

标签: c++pthreads

解决方案


当出现问题时,您不能保证核心转储。有一些错误,例如取消引用空指针,Linux 选择捕获并为您提供核心转储文件(在正确的模式下),但不能保证。事实上,很多逻辑错误都无法检测到,因此无法确定是否需要转储。

在两次锁定互斥体的情况下,这是“未定义的行为”,这意味着库保证会发生什么。在互斥锁的特殊情况下,可以深入研究实现以了解更多关于该特定实现如何处理它的信息。

但是,一般来说,值得注意的是 pthread 中有一个可重入互斥体,其唯一工作是在线程两次锁定互斥体时提供理智的行为。鉴于 pthreads 开发人员认为需要同时提供可重入和不可重入互斥体,这表明可以对互斥体锁定进行一些优化,这些优化只有在线程没有将其锁定两次时才是安全的。

在这种情况下,看起来您的库可能使用了一种锁定方案,该方案不知道哪个线程进行了锁定。因此,当您第二次锁定它时,它并没有意识到该线程已经锁定它,而是平静地等待线程自行解锁。

如果您尝试在一个线程上锁定互斥锁并在另一个线程上解锁它,则会发生一组相关的奇怪行为(如果您需要此行为,请改用信号量)


推荐阅读