C++ 多线程 std::thread join 与 detach

2024年3月22日
2020年8月7日
C++

发现先前我对 C++ 的 std::thread 的理解有很多错误和不明白的地方,现在我又去重新研究了一下。

线程在何时开始运行

线程在构造关联的线程对象时立即开始执行(等待任何OS调度延迟),从提供给作为构造函数参数的顶层函数开始。

这个纯粹是没有仔细读文档的问题。先前以为是在在调用 join 或者 detach 后才开始运行的,但在研究 join 时发现有出入,而且如果在 join 时开始运行,那和就单线程没有什么区别了。

join 与 detach

因为上一个问题,导致我对 join 的实际意义一直无法理解。但是现在可以捋顺了,join 函数的作用类似于 detach 加上锁的效果,join 函数会一直阻塞到对应线程退出为止。如果在 std::thread 对象析构前既没有使用 join 等待线程退出,也没有使用 detach 使线程独立运行,就会调用 std::terminate() 强制结束线程。

可以用多线程下载的场景展示 join 函数的用法。

std::thread download1(...);
std::thread download2(...);
// 在下载时就可以进行的任务
download1.join();
download2.join();
// 需要待所有内容都下载完再进行的任务

在大部分的场景下,使用 join 就可以实现了。而使用 detach 虽然可以获得更大的灵活度,但是需要自行解决同步的问题。