std::jthread是C++20新引入的线程类,与 std::thread 类似,或者说,jthread是对thread进一步的封装,功能更强大。
std::jthread的j实际上是joining的缩写,众所周知,std::thread在其生命周期结束时调用join()(让主线程等待该子线程完成,然后主线程再继续执行,对于不会停止的线程,不要使用join(),防止阻塞其他线程),或调用detach()(调用detach()进行线程分离,使其不影响其他线程运行,比如一个线程中无限循环执行的场景下,需要detach())。如果join()和detach()都没有被调用,析构函数将立即导致程序异常终止。C++20引入的std::jthread得以解决这个问题,std::jthread对象被析构时,会自动调用join(),等待执行流结束。
此外,std::jthread支持外部请求中止操作,调用join()后可能需要等待很长时间,甚至是永远等待。std::jthread除了提供std::stop_token能够主动取消或停止正在执行的线程,还增加了std::stop_callback允许在停止线程操作时调用一组回调函数。
来看看cpprefercence关于std::jthread::~jthread的解释:
std::jthread::~jthread Destroys the jthread object. If *this has an associated thread (joinable() == true), calls request_stop() and then join().
Notes
The request_stop() has no effect if the jthread was previously requested to stop.
A jthread object does not have an associated thread after
- it was default-constructed
- it was moved from
- join() has been called
- detach() has been called
If join() throws an exception (e.g. because deadlock is detected), std::terminate() may be called.
关于std::jthread::join的作用:阻塞当前线程直至 *this 所标识的线程结束其执行。
看例程:
#include <iostream> #include <thread> #include <chrono> void foo() { // 模拟耗费大量资源的操作 std::this_thread::sleep_for(std::chrono::seconds(1)); } void bar() { // 模拟耗费大量资源的操作 std::this_thread::sleep_for(std::chrono::seconds(1)); } int main() { std::cout << "starting first helper...\n"; std::jthread helper1(foo); std::cout << "starting second helper...\n"; std::jthread helper2(bar); std::cout << "waiting for helpers to finish..." << std::endl; helper1.join(); helper2.join(); std::cout << "done!\n"; }
输出结果如下:
starting first helper... starting second helper... waiting for helpers to finish... done!
std::jthread::joinable,主要是用来检查 std::jthread 对象是否标识活跃的执行线程,直接看cpprefercence相关例程:
#include <iostream> #include <thread> #include <chrono> void foo() { std::this_thread::sleep_for(std::chrono::seconds(1)); } int main() { std::jthread t; std::cout << "before starting, joinable: " << std::boolalpha << t.joinable() << '\n'; t = std::thread(foo); std::cout << "after starting, joinable: " << t.joinable() << '\n'; t.join(); std::cout << "after joining, joinable: " << t.joinable() << '\n'; }
输出结果如下:
before starting, joinable: false after starting, joinable: true after joining, joinable: false
可知如果 jthread 对象标识活跃的执行线程则为 true ,否则为 false 。