jthread¶
title: jthread 和 thread不同?
1. jthread 可以控制线程的取消/停止。(需要通过线程函数含std::stop_token参数,内部调用stop_token::stop_requested()判断)
2. jthread 析构时会自动join,执行线程。(析构先调用request_stop() 再调用 join())
- 功能:jthread 和 thread 功能一样,启动一个线程。
jthread
逻辑上保有一个内部的std::stop_source
类型私有成员,它维持共享停止状态。jthread
的构造函数接受一个 std::stop_token 作为其首参数,jthread
将从其内部的stop_source
传递它。这允许函数在其执行中检查是否已请求停止,而若已请求则返回
1 停止信号函数¶
get_stop_source
:返回与线程的停止状态关联的stop_source
对象get_stop_token
:返回与线程的共享停止状态关联的stop_token
对象request_stop
:请求执行经由线程的共享停止状态停止(发出停止信号,实际等价于get_stop_source().request_stop ()
)
3 stop_source¶
stop_source
类提供发出停止请求的方式。stop_source 包含 stop_token 对象。
4 stop_token¶
stop_token 内部有一个停止状态变量,可以检测这个状态,以便决定是否中止线程。类提供是否已经或能对其所关联的 std:: stop_source 对象作出停止请求的方法。 - 示例
int test_jthread()
{
auto worker1=[] (std::stop_token token,int i) {
std::cout<<"worker1 thread " << i<<"\n";
};
auto worker2=[] (int i) {
std::cout<<"worker2 thread "<< i<<"\n";
};
std::stop_token token;
std::jthread th1(worker1,1); // th1.get_stop_token() as the first argrment
std::jthread th2(worker2,2); //same as thread
std::jthread th3(worker1, token, 2); //same as thread
}
5 stop_callback¶
stop_callback
类模板提供对关联的 std:: stop_token 对象注册回调函数的 RAII 对象类型,使得将在 std:: stop_token 的关联 std:: stop_source 被请求停止时调用回调函数。
- 示例
//serializing the output with thread id
void sout(const char * s)
{
static std::mutex mtx;
const std::lock_guard<std::mutex> lock(mtx);
std::cout<<"["<<std::this_thread::get_id() <<"]"<<s<<'\n';
}
Void test_stopcallback()
{
sout("main thread");
auto worker=[] (std::stop_token token) {
sout("worker thread");
std::mutex mutex;
std::unique_lock lock(mutex);
std::condition_variable_any().wait(lock, token,
[&token] { return token.stop_requested(); });
sout("worker thread end");
};
std::stop_source source;
auto token=source.get_token();
std::stop_callback callback_stop(token, [] {
sout( "Stop callback executed");
});
std::jthread th(worker, token);
std::this_thread::sleep_for(std::chrono::seconds(1));
if(source.request_stop()) sout("stop OK");// 调用request_stop(),触发stop_callback的回调函数
}
- 可能输出
[139788821808960]main thread
[139788803913472]worker thread
[139788821808960]Stop callback executed
[139788821808960]stop OK
[139788803913472]worker thread end
2 示例¶
#include <chrono>
#include <iostream>
#include <thread>
using namespace ::std::literals;
int main() {
std::cout << std::endl;
std::jthread nonInterruptable([] { // (1)
int counter{0};
std::cout << "thread id: " << std::this_thread::get_id() << std::endl;
while (counter < 10) {
std::this_thread::sleep_for(0.2s);
std::cerr << "nonInterruptable: " << counter << std::endl;
++counter;
}
});
std::jthread interruptable([](std::stop_token itoken) { // (2)
int counter{0};
std::cout << "thread id: " << std::this_thread::get_id() << std::endl;
while (counter < 10) {
std::this_thread::sleep_for(0.2s);
if (itoken.stop_requested())// (3)处理线程停止信号
return;
std::cerr << "interruptable: " << counter << std::endl;
++counter;
}
});
std::this_thread::sleep_for(1s);
std::cerr << std::endl;
std::cerr << "Main thread interrupts both jthreads" << std::endl;
nonInterruptable.request_stop();//请求停止,但线程函数没有处理此信号
//interruptable.get_stop_source().request_stop();
interruptable.request_stop(); // (4)请求停止
std::cout << std::endl;
}
- 可能输出
[shw@rocky jthread]$ ./a.out
thread id: 140513660630592
thread id: 140513669023296
interruptable: 0
nonInterruptable: 0
nonInterruptable: 1
interruptable: 1
nonInterruptable: 2
interruptable: 2
nonInterruptable: 3
interruptable: 3
Main thread interrupts both jthreads
nonInterruptable: 4
nonInterruptable: 5
nonInterruptable: 6
nonInterruptable: 7
nonInterruptable: 8
nonInterruptable: 9