C++20 jthread

jthread是有自动合并和取消支持的 std::threadjthread包装了一下thread,提供了线程运行中停止的接口。jthread定义在<thread>头文件中。
使用取消功能需要用到std::stop_token。参考:<stop_token>
建议以后使用thread的都开始使用jthread,不必等到c++20出来。

  1. std::jthread对象销毁时,会调用join,等待其所表示的执行结束。
  2. 支持外部请求中止(通过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.hppstop_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的用法很有帮助。


  1. std::jthread与std::thread的区别是什么? ↩︎

  2. 《C++标准库(第2版)》、《C ++ 17 –完整指南》作者 ↩︎

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值