当前位置: 首页 > news >正文

C++20中线程类std::jthread的使用

      C++20中的std::jthread类表示一个执行线程。它与std::thread具有相同的常规行为,但std::jthread在析构(destruction)时会自动重新加入(rejoin),并且可以在某些情况下被取消/停止(cancelled/stopped)。

      与std::thread不同,std::jthread在逻辑上持有一个std::stop_source类型的内部私有成员,该成员维护一个共享的停止状态(stop-state)。std::jthread构造函数接受一个以std::stop_token作为第一个参数的函数,该参数由std::jthread从其内部std::stop_source传入。这使得该构造函数能够检查在执行过程中是否已请求停止,如果已请求则返回。

      std::jthread对象也可能处于不代表任何线程的状态(after default construction, move from, detach, or join),并且执行线程可能不与任何std::jthread 对象关联(after detach)。

      任何两个std::jthread对象都不能代表同一个执行线程;std::jthread不可拷贝构造或拷贝赋值,但可移动构造和移动赋值。

      如果std::jthead无法启动,则抛std::system_error异常。

      std::jthread构造函数的参数按值移动或拷贝。如果需要将引用参数传递给线程函数,则必须对其进行包装(例如,使用std::ref或std::cref)

      std::jthread的析构函数:如果当前线程有一个关联线程即joinable()为true,则会先调用request_stop(),然后再调用join()

      (1).如果std::jthread之前被请求stop,则调用request_stop()无效。

      (2).std::jthread对象在以下情况后没有关联线程:它是被默认构造的、它被移出(moved from)、已调用join()、已调用detach()。

      (3).如果join()抛出异常,则std::terminate()可能被调用。

      std::jthread中的函数:

      joinable():如果std::jthread对象标识了一个活动的执行线程,则返回true,否则返回false。已完成代码执行但尚未joined的线程仍被视为活动的执行线程,因此是jonable的

      get_id():返回std::jthread::id的值(std::thread::id的类型别名),用于标识与*this关联的线程。如果没有关联的线程,则返回默认构造的std::jthread::id。

      hardware_concurrency():静态函数,返回支持的并发线程数。该值仅供参考。如果该值定义不明确或无法计算,则返回0。

      join():阻塞当前线程,直到*this标识的线程完成执行。*this本身不执行同步。多个线程同时对同一个std::jthread对象调用join()会造成数据争用,从而导致未定义的行为。

      detach():将执行线程与std::jthread对象分离,允许继续独立执行。线程退出后,所有分配的资源都将被释放。调用detach后,*this不再拥有任何线程。

      swap:交换两个std::jthread对象的底层句柄。

      测试代码如下:

int test_jthread_constructor()
{auto func1 = [](int val) {for (auto i = 0; i < 2; ++i) {std::cout << ++val << std::endl;std::this_thread::sleep_for(100ms);}};auto func2 = [](int& val) {val = 88;};std::jthread jth1(func1, 5);std::jthread jth2{};std::cout << std::format("jth1 joinable: {}; jth2 joinable: {}", jth1.joinable(), jth2.joinable()) << std::endl;std::cout << "jth1 id: " << jth1.get_id() << "; jth2  id: " << jth2.get_id() << std::endl;jth2 = std::move(jth1);std::cout << std::format("jth1 joinable: {}; jth2 joinable: {}", jth1.joinable(), jth2.joinable()) << std::endl;std::cout << "jth1 id: " << jth1.get_id() << "; jth2  id: " << jth2.get_id() << std::endl;int val{ -1 };std::jthread jth3(func2, std::ref(val));jth3.join();std::cout << std::format("jth3 joinable: {}, val: {}", jth3.joinable(), val) << std::endl;std::cout << "jth3 id: " << jth3.get_id() << std::endl;std::cout << "concurrent threads are supported: " << std::jthread::hardware_concurrency() << std::endl;std::jthread jth4([] {std::cout << "jth4 running ..." << std::endl;std::this_thread::sleep_for(1s);std::cout << "jth4 end" << std::endl;});std::cout << "jth4 joinable: " << jth4.joinable() << ", id: " << jth4.get_id() << std::endl;jth4.detach();std::this_thread::sleep_for(3s);std::cout << "jth4 joinable: " << jth4.joinable() << ", id: " << jth4.get_id() << std::endl;jth4.swap(jth2);std::cout << std::format("jth2 joinable: {}; jth4 joinable: {}", jth2.joinable(), jth4.joinable()) << std::endl;std::swap(jth2, jth4);std::cout << std::format("jth2 joinable: {}; jth4 joinable: {}", jth2.joinable(), jth4.joinable()) << std::endl;return 0;
}

      执行结果如下图所示:

      get_stop_source():返回与std::jthread对象内部持有的相同共享停止状态相关联的std::stop_source。

      get_stop_token():返回与std::jthread对象内部持有的相同共享停止状态相关联的std::stop_token。

      request_stop():如果内部停止状态尚未收到停止请求,则向其发出停止请求。该判断以原子方式进行,如果已发出停止请求,则停止状态将以原子方式更新,以避免竞争条件(race conditions)。request_stop()只是向线程的std::stop_token发送"尽快退出"的信号,线程函数内要主动检查std::stop_token的stop_requested(),然后自行结束循环,不会结束线程,因此再调用joinable()还是true

int test_jthread_request_stop()
{std::jthread jth([](std::stop_token token) {while (!token.stop_requested()) {std::cout << "running ...\n";std::this_thread::sleep_for(500ms);}std::cout << "stopped\n";});std::this_thread::sleep_for(3s);std::cout << "jth joinable: " << jth.joinable() << ", id: " << jth.get_id() << std::endl;jth.request_stop();std::this_thread::sleep_for(1s);std::cout << "jth joinable: " << jth.joinable() << ", id: " << jth.get_id() << std::endl;return 0;
}

      执行结果如下图所示:

      std::jthread和std::thread区别:

      (1).std::jthread析构时会自动join(),无需手动调用join(),而std::thread析构前必选手动join()或detach()。

      (2).std::jthread内置停止令牌(stop_token),可通过std::stop_token请求线程停止

      (3).std::jthread兼容std::thread大多数接口。

      (4).std::jthread比std::thread更安全。

      GitHub:https://github.com/fengbingchun/Messy_Test

http://www.dtcms.com/a/415752.html

相关文章:

  • 拍卖行 网站建设爱奇艺的网站是用什么做的
  • 智能问答场景下的AI算力平台建设指南——从硬件选型到弹性扩展的全流程实践
  • 绍兴网站建设优化网页设计制作
  • 网站降权了怎么办天元建设集团有限公司2008年招聘
  • (二)routeros命令笔记:无线篇
  • 网站开发 高级认证专业的营销型网站企业文化
  • 富文本编辑器Tinymce的使用、图片可编辑尺寸、自定义plugin(数学公式)、自定义icons
  • [创业之路-611]:半导体行业供应链 - 半导体原材料 - 电子特气
  • DreamBoards 推出 DreamHAT+ 雷达扩展板,为树莓派带来 60GHz 毫米波雷达
  • 做旅游网站都需要的调查在哪个网站可做网络夫妻
  • Coze源码分析-资源库-删除数据库-后端源码-领域服务/数据访问层
  • 游戏网站平台大全游戏网网站团购活动页面怎么做
  • Elasticsearch 从入门到实战
  • 网站如何调用手机淘宝做淘宝客佛山品牌策划设计
  • 氛围编程有哪些成功案例?
  • 网站优化外包推荐衡水企业做网站多少钱
  • 有哪些网站程序重庆网站建设的意义
  • Android开发-应用广播
  • AI 算力加速指南:Figma AI/Canva AI 全场景优化,从 “闪退卡顿” 到 “流畅创作”(一)
  • C++/C#游戏开发引擎和2D/3D图形库
  • 企业网站建设课件商业招商网站
  • 上海网站建设sheji021抖音代运营多少钱
  • 快递网站模版建网站公司汽车六万公里是否累变速箱油
  • 搭建了虚拟局域网,飞牛NAS的防火墙还需要开吗?
  • 中小学网站建设探讨海外网络推广外包
  • 安徽网站设计流程xp系统没有lls组件可以做网站吗
  • Mac中XXX将对您的电脑造成伤害, 您应该将它移到废纸篓
  • 广州市做网站公司品牌展柜设计制作
  • 计算机视觉进阶教学之dlib库(二)
  • 石家庄网站制作方案衡阳seo排名