c++ - 为什么我在同一个线程中使用 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 互斥锁默认是非递归互斥锁,我的程序中只有一个线程,所以当我两次锁定这个互斥锁时,它应该是崩溃的。
解决方案
当出现问题时,您不能保证核心转储。有一些错误,例如取消引用空指针,Linux 选择捕获并为您提供核心转储文件(在正确的模式下),但不能保证。事实上,很多逻辑错误都无法检测到,因此无法确定是否需要转储。
在两次锁定互斥体的情况下,这是“未定义的行为”,这意味着库不保证会发生什么。在互斥锁的特殊情况下,可以深入研究实现以了解更多关于该特定实现如何处理它的信息。
但是,一般来说,值得注意的是 pthread 中有一个可重入互斥体,其唯一工作是在线程两次锁定互斥体时提供理智的行为。鉴于 pthreads 开发人员认为需要同时提供可重入和不可重入互斥体,这表明可以对互斥体锁定进行一些优化,这些优化只有在线程没有将其锁定两次时才是安全的。
在这种情况下,看起来您的库可能使用了一种锁定方案,该方案不知道哪个线程进行了锁定。因此,当您第二次锁定它时,它并没有意识到该线程已经锁定它,而是平静地等待线程自行解锁。
如果您尝试在一个线程上锁定互斥锁并在另一个线程上解锁它,则会发生一组相关的奇怪行为(如果您需要此行为,请改用信号量)
推荐阅读
- javascript - 从 A 框架中的文本实体中检索文本的正确方法
- c# - xamarin 更新标签被更改为不同的活动而被杀死
- html - 如何将元素与附加到其父元素底部的表格顶部对齐?
- python - 使用 ElementTree 提取
- algorithm - “Exact Cover”维基百科详细示例,关于最后一步的问题
- ruby-on-rails - 意外标记:使用 Uglifier 时 ES6 类上的运算符 (=)
- css - 如何一键多次更改按钮的背景颜色?
- c# - 从控制器下载 zip 文件不显示下载或任何错误
- php - 如何使用 PHP 打印 CSV 文件的行?
- css - CSS 未应用于单独的 ejs 文件