C++20线程库增加的内容主要包括两方面:jthread及相关的stop_token等;用于线程同步的semaphore等。
一、joinable和stoppable的jthread
1. jthread
std::jthread也在<thread>中定义,基本与std::thread相同,不同在于:
- 在析构时,自动join到主线程,此时写法上比单纯用sth::thread简洁些
- 可以在线程外终止此线程的执行,jthread内部有一个std::stop_source对象,而stop_source又可关联stop_token,stop_callback,它们共同实现外部状态通知等功能。
为完成上面功能2,jthread的入口函数与thread稍有不同,如果入口函数f定义的第一个参数是std::stop_token而调用时并没有给,则jthread会自动将自身维护的stop_token作为第一个参数传给入口函数,即jthread内部在调用入口函数f时,会有如下的两种形式:
1 std::invoke(decay_copy(std::forward<Function>(f)),
decay_copy(std::forward<Args>(args))...);
2 std::invoke(decay_copy(std::forward<Function>(f)),
get_stop_token(),
decay_copy(std::forward<Args>(args))...);
其中1与thread的方式相同,2是将内部的stop_token作为第一个参数传给入口函数,而外部提供给入口函数的参数中可不包含stop_token。下例中,三种使用jthread都是正确的。
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 f