为什么即使调用了析构函数,C++11 中的分离线程也可以执行

Why can detached thread in C++11 execute even if the destructor has been called

本文关键字:分离 线程 执行 也可以 C++11 调用 析构函数 为什么      更新时间:2023-10-16

我刚刚在 C++11 年阅读了有关std::thread.detach()的文档。

这是我的测试:

#include <iostream>
#include <thread>
#include <chrono>
static int counter = 0;    
void func()
{
while (true) {
std::cout<<"running..."<<std::endl;
std::cout<<counter++<<std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
}

int main()
{
{
std::thread t(func);
t.detach();
} // t is released after this line
// t has died, so who is holding the resources of the detached thread???
std::cin.get();
return 0;
}

此代码按预期工作。因此,即使调用了线程的析构函数,线程似乎也可以继续运行。这是真的吗?

如果这是真的,那么在对象t被释放后,到底谁掌握着线程的资源?是否有某种机制来保存资源,例如隐藏的匿名对象?

在C++中,std::thread不管理执行线程本身。C++根本没有用于管理执行线程的控件。

std::thread管理线程句柄- 线程的标识符(在Posix世界中thread_t,这在很大程度上是std::thread的模型(。这种标识符用于与线程通信(如控制(,但C++,唯一的标准通信方式是join线程(只是等待线程完成(或从线程detach

调用析构函数时std::thread线程句柄也会被破坏,并且无法进一步控制线程。但是执行线程本身仍然存在,并继续由实现(或者更准确地说,操作系统(管理。

请注意,对于非分离线程,如果线程尚未连接,则std::thread析构函数将引发异常。这只是一种保护措施,防止开发人员在无意中意外丢失线程句柄。

您是正确的,如果在线程的析构函数之后分离,线程将继续运行。

地球上没有人拥有资源(除非你安排某人这样做(。 但是,当应用程序退出时,应用程序关闭过程将结束线程。

人们仍然可以安排与分离的线程进行通信并"等待"分离的线程。 从本质上讲,join()是一个方便的 API,因此您不必执行以下操作:

#include <atomic>
#include <chrono>
#include <iostream>
#include <thread>
static int counter = 0;    
std::atomic<bool> time_to_quit{false};
std::atomic<bool> has_quit{false};
void func()
{
while (!time_to_quit) {
std::cout<<"running..."<<std::endl;
std::cout<<counter++<<std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
has_quit = true;
}

int main()
{
{
std::thread t(func);
t.detach();
} // t is released after this line
using namespace std::chrono_literals;
std::this_thread::sleep_for(3s);
time_to_quit = true;
while (!has_quit)
;
std::cout << "orderly shutdownn";
}

执行线程独立于用于在C++中管理它们的线程对象而存在。 分离线程对象时,执行线程将继续运行,但实现(通常与操作系统结合使用(负责它。