如果我不加入主线程,为什么要使用线程转储核心

时间:2019-09-12 11:32:17

标签: multithreading

#include<iostream>
#include<thread>
using namespace std;
int main()
{
    thread t1([]{
        cout<<"Hi";
        });
    //t1.join();
    return 0;
}

如果我要评论t1.join(),则会生成转储。

1 个答案:

答案 0 :(得分:0)

真正但无趣的答案是因为这是线程库的实现者对其进行编程所要做的。

更有趣的答案是为什么,他们将其编程为具有这种行为。他们在这种情况下会出现线程恐慌的原因是使一个晦涩的问题更加明显(从而更容易及早发现和解决问题)。

一个模糊的问题是竞争条件:进程的C或C ++运行时在调用main()之前设置了一些进程范围的共享资源(例如,环境变量名称表,stdio缓冲区等),然后流泪它们在main()返回之后(但在进程销毁之前)再次下降。在单线程程序中,这没问题,因为您的单线程代码永远不会在main()之前或之后执行,因此您的代码永远不必担心在格式不完整的数据结构中使用它们。状态。

但是,如果您开始运行第二个线程,并且在main()返回之后该线程仍在运行,则意味着您的线程尝试访问这些进程范围数据之一的机会很小(但非零)在运行时忙于清理和删除它的确切时刻,从而以某种不确定的/半毁坏的状态“看到”它,这是不安全的。这种现象的症状是,有时(例如,每百次运行一次,甚至更少)您的程序在退出时会神秘地崩溃(或其他行为不当),并且您可能很难弄清为什么会这样,并且修复它。

解决此问题的方法是确保退出线程之前main()在线程上调用join(),以便您可以确保在开始清理数据结构时线程不再运行。还有故意恐慌陷阱可以确保您立即意识到自己需要这样做(或者致电detach()表示您已意识到问题所在,不在乎-但如果是这样, ,您最好知道自己在做什么,否则您将回到正题)