发现先前我对 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
虽然可以获得更大的灵活度,但是需要自行解决同步的问题。