std::jthread与std::thread区别
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 。
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
2021-05-18 公网可用的RTMP、RTSP测试地址(更新于2021年3月)
2021-05-18 rtmp/rtsp/hls公网真正可用的测试地址
2021-05-18 Windows平台RTMP|RTSP播放器实现画面全屏功能
2021-05-18 Windows平台RTMP|RTSP播放器为什么要兼容GDI绘制
2021-05-18 Windows平台RTMP推送|轻量级RTSP服务实现本地摄像头|屏幕|叠加数据预览
2021-05-18 Android对接实现内网无纸化会议|智慧教室|实时同屏功能
2021-05-18 QT实现低延迟的RTSP、RTMP播放器