分离的 std::thread 终止后是不是需要删除?

Posted

技术标签:

【中文标题】分离的 std::thread 终止后是不是需要删除?【英文标题】:Does a detached std::thread need to be deleted after it terminates?分离的 std::thread 终止后是否需要删除? 【发布时间】:2016-02-04 03:07:58 【问题描述】:

我创建一个new std::thread 对象,然后创建detach() 它。线程运行任意时间,然后自行终止。由于我使用new 创建了对象,我是否需要在某些时候delete 来释放它的资源?还是线程在终止时有效地delete 本身?

如果它本身有效地delete,如果我在它终止后明确地delete 它会发生什么不好的事情吗?

【问题讨论】:

小心,您使用的是“它”这个词,有时很难判断您是指线程本身还是 std::thread 对象。 一个很好的方法来启动一个分离的thread:std::thread(f, a0, a1, ...).detach(); 不需要新的。无需删除它。没有机会忘记detach() 它。在您的构造和分离点之间不会引发异常。 @DavidSchwartz 不确定我是否理解 - 为什么线程和 std::thread 对象不同? @StuartBarth 线程是一种执行工具,它可能有也可能没有相应的 std::thread 对象。 std::thread 对象是 C++ 类的实例,它可能有也可能没有相应的线程。例如,您说“线程是否在终止时有效地删除自己”。这意味着什么?您是否在询问线程终止时线程是否删除了 std::thread 对象?显然它不能,因为如果构造 std::thread 的线程在线程终止时访问该对象,那将导致灾难。这就是你要问的吗? 【参考方案1】:

是的,你必须自己delete

一旦调用std::thread::detach,线程将与线程对象分离并允许独立继续执行,然后线程对象将不再拥有任何线程。所以线程不会也不可能在终止时delete

【讨论】:

我不明白这个So the thread won't and impossible to delete it upon termination.。您的意思是The thread will not be deleted after terminating its execution and ... 终止后无法删除的内容?你的意思是我不能在线程终止后删除它?我怎么知道线程何时终止?我如何对线程进行编程以在它终止后自行删除? 我是否可以通过不使用new 创建线程来对线程进行编程以在其终止后自行删除,然后,我可以调用std::thread(...).detach() 并且线程将在其终止时自动释放? (如文档所述:en.cppreference.com/w/cpp/thread/thread/detachSeparates the thread of execution from the thread object, allowing execution to continue independently. Any allocated resources will be freed once the thread exits. @user 我的意思是delete 线程对象。例如对于std::thread * t = new std::thread(...); t->detach();,则必须手动编写delete t;。从线程对象中分离和执行的线程不能这样做。 谢谢!如果我理解正确,在调用std::thread * t = new std::thread(...); t->detach(); 之后,即使线程仍在运行,我也可以使用delete t; 删除线程,因为该线程现在不受我的应用程序控制,但操作系统正在处理其资源分配/释放,直到线程退出并被操作系统完全删除。 所以如果你只说 std::thread t = std:thread(...); 创建一个具有本地范围的线程,然后分离它,当函数退出时,t 将被删除,但是分离的线程会继续进行,对吗?只要没有本地范围捕获..【参考方案2】:

C++ 中使用new 分配的每个 对象必须使用delete 释放。

线程是一个“位于操作系统内”的对象(通常)。它使用std::thread 构造函数创建并使用detach() 发布。

std::thread 类的对象是一个 С++ 对象,与线程相关联。

所以你必须同时发布 - 操作系统对象和 C++ 对象。


更新。创建线程时,操作系统会在kernelspace 中分配内部结构来控制它。每个线程都有一组属性,例如状态(运行、挂起、等待资源)、优先级、返回码等。

【讨论】:

谢谢——你能详细说明什么是“位于操作系统内”的线程对象吗?我猜这与@DavidSchwartz 的评论有关? @Stuart Barth 更新了答案

以上是关于分离的 std::thread 终止后是不是需要删除?的主要内容,如果未能解决你的问题,请参考以下文章

如何终止或停止 C++ 中的分离线程?

父线程离开其块后分离的 std::thread 的情况

在处理异常后阻止线程在分离时调用std :: terminate()

std::thread 线程在对象中分离,它何时终止?

linux C++ std::thread::detach()函数(线程分离)

如何使用 QThread 创建一个分离的线程,就像在 std::thread 中一样