为什么必须在线程销毁之前调用 join() 或 detach()? [英] Why must one call join() or detach() before thread destruction?

查看:219
本文介绍了为什么必须在线程销毁之前调用 join() 或 detach()?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不明白为什么当 std::thread 被破坏时,它必须处于 join() 或 detach() 状态.

I don't understand why when an std::thread is destructed it must be in join() or detach() state.

Join 等待线程完成,而 detach 不会.似乎有一些我不理解的中间状态.因为我的理解是 join 和 detach 是互补的:如果我不调用 join() 则 detach() 是默认值.

Join waits for the thread to finish, and detach doesn't. It seems that there is some middle state which I'm not understanding. Because my understanding is that join and detach are complementary: if I don't call join() than detach() is the default.

这样说吧,假设您正在编写一个程序来创建一个线程,并且只有在该线程生命周期的后期才调用 join(),所以在您调用 join() 之前,该线程基本上像它一样运行分离,不是吗?

Put it this way, let's say you're writing a program that creates a thread and only later in the life of this thread you call join(), so up until you call join the thread was basically running as if it was detached, no?

逻辑上 detach() 应该是线程的默认行为,因为这是线程的定义,它们是并行执行的,与其他线程无关.

Logically detach() should be the default behavior for threads because that is the definition of what threads are, they are parallelly executed irrespective of other threads.

那么当线程对象被破坏时,为什么会调用 terminate() 呢?为什么标准不能简单地将线程视为分离的?

So when the thread object gets destructed why is terminate() called? Why can't the standard simply treat the thread as being detached?

我不明白在线程被破坏之前没有调用 join() 或 detached() 时终止程序背后的基本原理.这样做的目的是什么?

I'm not understanding the rationale behind terminating a program when either join() or detached() wasn't called before the thread was destructed. What is the purpose of this?

更新:

我最近遇到了这个.Anthony Williams 在他的著作 Concurrency In Action 中指出,C++17 的一个提议是加入一个类似于 std::thread 的 join_thread 类,除了它会像 scoped_thread 一样自动加入析构函数.这在委员会中没有得到共识,所以它没有被标准接受(尽管它仍然在 C++20 作为 std::jthread 的轨道上)......"

I recently came across this. Anthony Williams states in his book, Concurrency In Action, "One of the proposals for C++17 was for a joining_thread class that would be similar to std::thread, except that it would automatically join in the destructor much like scoped_thread does. This didn’t get consensus in the committee, so it wasn’t accepted into the standard (though it’s still on track for C++20 as std::jthread)..."

推荐答案

从技术上讲,答案是因为规范是这么说的",但这是一个迟钝的答案.我们无法读懂设计师的想法,但以下是一些可能造成的问题:

Technically the answer is "because the spec says so" but that is an obtuse answer. We can't read the designers' minds, but here are some issues that may have contributed:

使用POSIX pthreads,子线程在退出后必须加入,否则它们会继续占用系统资源(就像内核中的进程表条目).这是通过 pthread_join().如果进程持有子线程的 HANDLE,Windows 也有类似的问题;尽管 Windows 不需要完全连接,但该过程仍必须调用 CloseHandle() 释放它在线程上的引用计数.

With POSIX pthreads, child threads must be joined after they have exited, or else they continue to occupy system resources (like a process table entry in the kernel). This is done via pthread_join(). Windows has a somewhat analogous issue if the process holds a HANDLE to the child thread; although Windows doesn't require a full join, the process must still call CloseHandle() to release its refcount on the thread.

由于 std::thread 是一个跨平台的抽象,它受到需要连接的 POSIX 要求的约束.

Since std::thread is a cross-platform abstraction, it's constrained by the POSIX requirement which requires the join.

理论上,std::thread 析构函数可以调用 pthread_join() 而不是抛出异常,但这(主观上)可能会增加死锁的风险.而正确编写的程序会知道何时在安全的时间插入连接.

In theory the std::thread destructor could have called pthread_join() instead of throwing an exception, but that (subjectively) that may increase the risk of deadlock. Whereas a properly written program would know when to insert the join at a safe time.

另见:

这篇关于为什么必须在线程销毁之前调用 join() 或 detach()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆