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 。