vs2019 C++20 jthread
-
- 01 jthread的一個實作
- 02 jthread用法
-
- 02.01 cppreference上面的介紹
- 02.02 可協作中斷的用法
- 02.03 NICOLAI JOSUTTIS提供了大量測試用例
jthread
是有自動合并和取消支援的
std::thread
。
jthread
包裝了一下
thread
,提供了線程運作中停止的接口。
jthread
定義在
<thread>
頭檔案中。
使用取消功能需要用到
std::stop_token
。參考:<stop_token>
建議以後使用thread的都開始使用jthread,不必等到c++20出來。
- std::jthread對象銷毀時,會調用join,等待其所表示的執行結束。
-
支援外部請求中止(通過get_stop_source、get_stop_token和request_stop)。
std::jthread為了實作上述新功能,帶來了額外的性能開銷(主要是多了一個成員變量)。而根據C++一直以來“不為不使用的功能付費”的設計哲學,他們自然就把這些新功能拆出來新做了一個類。1
01 jthread的一個實作
NICOLAI JOSUTTIS [尼古拉·喬蘇蒂斯]2關于jthread的一個實作:
https://github.com/josuttis/jthread
這個實作沒有使用C++20的新特性。隻有
jthread.hpp
和
stop_token.hpp
兩個檔案,700多行代碼。
https://github.com/josuttis/jthread/blob/master/source/jthread.hpp
https://github.com/josuttis/jthread/blob/master/source/stop_token.hpp
02 jthread用法
文中所有提到的代碼,整理在:https://github.com/5455945/cpp_demo/tree/master/C%2B%2B20/jthread
02.01 cppreference上面的介紹
jthread在基本用法上面完全相容thread。
https://zh.cppreference.com/w/cpp/thread/jthread/jthread
// https://zh.cppreference.com/w/cpp/thread/jthread/jthread
#include <iostream>
#include <utility>
#include <thread>
#include <chrono>
#include "jthread.hpp" // https://github.com/josuttis/jthread/tree/master/source
void f1(int n)
{
for (int i = 0; i < 5; ++i) {
std::cout << "Thread 1 executing\n";
++n;
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
}
void f2(int& n)
{
for (int i = 0; i < 5; ++i) {
std::cout << "Thread 2 executing\n";
++n;
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
}
class foo
{
public:
void bar()
{
for (int i = 0; i < 5; ++i) {
std::cout << "Thread 3 executing\n";
++n;
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
}
int n = 0;
};
class baz
{
public:
void operator()()
{
for (int i = 0; i < 5; ++i) {
std::cout << "Thread 4 executing\n";
++n;
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
}
int n = 0;
};
void test_jthread_cppreference01()
{
int n = 0;
foo f;
baz b;
std::jthread t0; // t0 不是線程
std::jthread t1(f1, n + 1); // 按值傳遞
std::jthread t2a(f2, std::ref(n)); // 按引用傳遞
std::jthread t2b(std::move(t2a)); // t2b 現在運作 f2() 。 t2a 不再是線程
std::jthread t3(&foo::bar, &f); // t3 在對象 f 上運作 foo::bar()
std::jthread t4(b); // t4 在對象 b 上運作 baz::operator()
t1.join();
t2b.join();
t3.join();
std::cout << "Final value of n is " << n << '\n';
std::cout << "Final value of foo::n is " << f.n << '\n';
// t4 在析構時結合
}
02.02 可協作中斷的用法
參考 C ++ 20中的新線程(jthread)功能
使用
request_stop()
向
jthread
線程發送停止線程請求;在
jthread
線程中使用
stop_requested()
來判斷是否收到停止線程請求。如果收到停止請求,即做出退出線程反應。
void sleep(const int seconds) {
std::this_thread::sleep_for(std::chrono::seconds(seconds));
}
void test_jthread03() {
std::jthread jt{ [](std::stop_token st) {
while (!st.stop_requested()) { // 有停止線程請求的處理
std::cout << "Doing work\n";
sleep(1);
}
} };
sleep(5);
jt.request_stop(); // 請求線程停止,因有響應停止請求而終止線程
jt.join();
}
02.03 NICOLAI JOSUTTIS提供了大量測試用例
https://github.com/josuttis/jthread/tree/master/source中提供了大量測試用例,對了解jthread的用法很有幫助。
- std::jthread與std::thread的差別是什麼? ↩︎
- 《C++标準庫(第2版)》、《C ++ 17 –完整指南》作者 ↩︎