为什么这个简单的线程c++程序在退出时崩溃,除非我调用thread.join()

Why does this simple threaded C++ program crash upon exit unless I call thread.join()?

本文关键字:非我 崩溃 调用 thread join 退出 简单 线程 程序 c++ 为什么      更新时间:2023-10-16

下面的程序最终将失败,并显示有关abort()被调用的消息。

我开始一个线程,简单打印到cout。如果我用std::this_thread::sleep_for(),我得到错误。如果移除这个,就会出现错误。如果我在线程上调用join(),一切工作正常。

线程不应该在1000毫秒延迟结束之前就终止吗?为什么这会导致错误?我不敢相信调用join()是一个线程的要求。

#include <thread>
#include <iostream>
class ThreadTest
{
public:
    ThreadTest() : _t{ &ThreadTest::Run, this } {}
    void Wait() { _t.join(); }
private:
    void Run(){
        std::cout << "In thread" << std::endl;
    }
    std::thread _t;
};
int main(int argc, char *argv[])
{
    ThreadTest tt;
    std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    // tt.Wait();
    return 0;
}

根据线程类析构函数的cppreference:

~thread() :销毁线程对象。如果 *this 仍然有一个相关联的正在运行的线程(即 joinable() == true ),则调用 std::terminate()

And joinable():

[…一个线程如果已经完成了代码的执行,但是还没有被join,它仍然被认为是一个活动的正在执行的线程,因此是可join的。

所以你必须在你的线程变量被自动销毁或使用detach()成员函数之前显式地调用join()

查看cppreference的std::thread页面

如果一个线程已经完成了代码的执行,但是还没有被连接,那么它仍然被认为是一个正在执行的活动线程,因此是可连接的。

[the destructor]销毁线程对象。如果*this还有一个相关联的运行线程(即joinable() == true),则调用 std::terminate()

要获得你想要的行为,你需要在退出main之前调用_t.detach():

[detach()]将正在执行的线程从线程对象中分离出来,允许独立地继续执行。一旦线程退出,任何分配的资源都将被释放。调用detach后,*this不再拥有任何线程。

相关文章: