C++20新特性之std::jthread和chrono库扩展

 更新时间:2026年06月04日 09:27:18   作者:gccbuaa  
C++20标准库特性2.3 std::jthread2.3.1 jthread 语法格式 常用方法2.3.2 总结2.4 chrono库扩展2.4.1 语法格式与核心概念2.4.1.1 日历类型创建2.4.1.2 ok() 判断有效性2.4.1.3 常用方法2.4.2 举例 本文记录

本文记录C++20新特性之std::jthread和chrono库扩展。

 std::jthread

在C++11的thread是,如果忘记 join()( 让主线程等待子线程结束) 或者 detach()分离线程,当std::thread析构时,程序会直接调用terminate()崩溃。
在C++20中引入了 jthread,就是为了遵循RAII原则,析构时自动调用 join(),保证程序不崩溃。

1 jthread 语法格式 常用方法

stdL::jthread 与 C++11的thread都包含在 头文件中,使用方式基本一致,新功能如下:
1 自动join(),当 std::jthread 对象离开作用域时,如果线程还在运行,主线程等待子线程结束(join)。
示例1:jthread基本使用
jthread析构时自动调用join() ,示例如下:

void worker() {
std::cout << "Working..." << std::endl;
}
void test()
{
// 语法与 std::thread 一样
std::jthread t(worker);
// 不需要手动调用join(),而是test()结束时,t析构,自动等待线程完成
}

2 协作式中断:线程函数可以接收一个 std::stop_token 参数,用于检查外部是否请求停止。

  • request_stop(): 外部调用,请求线程停止。
  • get_stop_token(): 获取关联的停止令牌。
  • stop_requested(): 在线程内部检查是否收到了停止请求。

示例2,子线程运行2秒,在主线程中请求子线程停止。

void interruptibleWorker(std::stop_token stoken)
{
while (true)
{
// 定期检查是否请求停止
if (stoken.stop_requested())
{
std::cout << "Stopping work..." << std::endl;
break;
}
// 模拟工作
std::cout << "Working..." << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(200));
}
}
void test()
{
std::jthread t(interruptibleWorker);
std::this_thread::sleep_for(std::chrono::seconds(2));
// 手动请求停止
t.request_stop();
/*
Working...
Working...
Working...
Working...
Working...
Working...
Working...
Working...
Working...
Working...
Stopping work...
*/
}

2 总结

jthread 是现代C++多线程的首选,jthread更安全,利用了RAII特性,避免了忘记join()导致的崩溃。
内置 std::stop_token,提供了一套标准的、线程安全的停止机制,替代了过去常用的 bool is_running 标志位。
建议,在C++20以后的项目中使用jthread代替thread.

chrono库扩展

在C++11中引入了,提供了高精度的计时功能,但是在日历和时区的处理上几乎是一片空白。比如,
缺乏日历计算:计算“下个月的今天是星期几”,不容易实现。
没有时区支持:无法原生处理 UTC 与本地时间的转换。
类型不安全:struct tm 中的月份从 0 开始,年份从 1900 开始,极易出错。
C++20 将 Howard Hinnant 的 date 库正式纳入标准,让 C++ 终于拥有了日期和时区处理能力。

1 语法格式与核心概念

1.1 日历类型创建

在C++20中,可以使用 / 运算符来组合 年月日。

void test()
{
// 创建一个日期:2023年10月24日
auto date1 = 2023y / 10 / 24; // 年月日
auto date2 = 24d / 10 / 2023y; // 日月年
auto date3 = October / 24 / 2023y; // 直接使用月份名称
std::cout << "Date1: " << date1 << std::endl;
// Date1: 2023-10-24
std::cout << "Date2: " << date2 << std::endl;
// Date2: 2023-10-24
std::cout << "Date3: " << date3 << std::endl;
// Date3: 2023-10-24
}

1.2 ok() 判断有效性

创建一个日期,并判断有效性。

auto d = 2023y / 2 / 30; // 2月没有30号
if (!d.ok()) {
std::cout << "Invalid Date!" << std::endl;
}

1.3 常用方法

A 日历组件

  • std::chrono::year, month, day: 基础单位。
  • std::chrono::weekday: 星期几(支持 Monday, Tuesday 等常量)。
  • std::chrono::year_month_day: 完整的日期结构。
  • std::chrono::sys_days: 基于系统时钟的天数精度时间点(通常用于转换)。
    B. 时区组件 (Time Zones)
  • std::chrono::locate_zone(“Name”): 获取特定时区(如 “Asia/Shanghai”)。
  • std::chrono::current_zone(): 获取当前系统时区。
  • std::chrono::zoned_time: 结合了时间点和时区的对象。
void test()
{
auto now = system_clock::now();
cout << "Current time: " << now << endl;
// Current time: 2025-12-03 03:01:12.5341520
// 转为纽约时间
auto ny_tz = zoned_time{ "America/New_York", now };
cout << "New York time: " << ny_tz << endl;
// New York time: 2025-12-02 22:01:12.5341520 GMT-5
// 转为上海时间
// 转换为上海时间
auto sh_time = zoned_time{ "Asia/Shanghai", now };
cout << "Shanghai time: " << sh_time << endl;
// Shanghai time: 2025-12-03 11:01:12.5341520 GMT+8
}

C 新的时钟

  • std::chrono::utc_clock: 协调世界时(考虑闰秒)。
  • std::chrono::file_clock: 用于文件系统的时间(std::filesystem::last_write_time)。

2 举例

示例1:计算“2024年每个月的最后一个星期五”,用于生成定期报表任务。

void list_report_days(int yearNum)
{
year y{ yearNum };
for (auto m = 1; m <= 12; ++m)
{
month mo{ static_cast<unsigned>(m) };
  // 语法糖:year_month_day_last 表示某月的最后一天
  auto last_day_of_month = y / mo / last;
  // 转换为 sys_days 以便进行星期计算
  sys_days sd = last_day_of_month;
  // 找到这个月的最后一个星期五
  // weekday_last 表示“最后一个星期X”
  auto last_friday = y / mo / Friday[last];
  std::cout << last_friday << std::endl;
  }
  /*
  2025/Jan/Fri[last]
  2025/Feb/Fri[last]
  2025/Mar/Fri[last]
  2025/Apr/Fri[last]
  2025/May/Fri[last]
  2025/Jun/Fri[last]
  2025/Jul/Fri[last]
  2025/Aug/Fri[last]
  2025/Sep/Fri[last]
  2025/Oct/Fri[last]
  2025/Nov/Fri[last]
  2025/Dec/Fri[last]
  */
  }
  void test()
  {
  list_report_days(2025);
  }

示例2:跨国会议时间转换
服务器收到一个 UTC 时间戳,需要将其转换为用户所在时区(例如东京)的本地时间字符串显示给用户。

void print_meeting_time(system_clock::time_point utc_tp, std::string_view user_zone) {
try {
// 1. 创建带时区的时间对象
auto zt = zoned_time{ user_zone, utc_tp };
// 2. 直接输出,自动处理偏移量
// C++20 的 format 支持 chrono 类型
std::cout << std::format("Meeting time in {}: {:%Y-%m-%d %H:%M %Z}\n",
user_zone, zt);
}
catch (const std::runtime_error& e) {
std::cout << "Unknown time zone: " << user_zone << std::endl;
}
}
int test()
{
auto meeting_utc = system_clock::now();
print_meeting_time(meeting_utc, "Asia/Shanghai");
// Meeting time in Asia/Shanghai: 2025-12-03 11:09 GMT+8
print_meeting_time(meeting_utc, "Europe/London");
// Meeting time in Europe/London: 2025-12-03 03:09 GMT
print_meeting_time(meeting_utc, "America/Los_Angeles");
// Meeting time in America/Los_Angeles: 2025-12-02 19:09 GMT-8
return 0;
}

到此这篇关于C++20新特性之std::jthread和chrono库扩展的文章就介绍到这了,更多相关C++20 std::jthread和chrono库内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 数据结构之矩阵行列和相等的实例

    数据结构之矩阵行列和相等的实例

    这篇文章主要介绍了数据结构之矩阵行列和相等的实例的相关资料,希望通过本文能帮助到大家,让大家掌握这部分内容,需要的朋友可以参考下
    2017-10-10
  • C语言超详细讲解指向函数的指针

    C语言超详细讲解指向函数的指针

    C语言程序在编译后,每个函数都有一个首地址(也就是函数第一条指令的地址),这个地址称为函数的指针。可以定义指向函数的指针变量,使用指针变量间接调用函数
    2022-07-07
  • C++结构体用法实例分析

    C++结构体用法实例分析

    这篇文章主要介绍了C++结构体用法,实例分析了默认构造函数,复制构造函数,运算符重载等使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-01-01
  • C++通过类实现控制台贪吃蛇

    C++通过类实现控制台贪吃蛇

    这篇文章主要为大家详细介绍了C++通过类实现控制台贪吃蛇,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-04-04
  • C++文件的操作及小实验示例代码详解

    C++文件的操作及小实验示例代码详解

    这篇文章主要介绍了C++文件的操作及小实验,对于文件,它是一个流对象,对文件的操作无非是读和写,通过本文的学习大家将会理解文件的具体操作
    2022-05-05
  • Pthread并发编程之线程基本元素和状态的剖析

    Pthread并发编程之线程基本元素和状态的剖析

    本篇文章主要给大家介绍pthread并发编程当中关于线程的基础概念,并且深入剖析进程的相关属性和设置,以及线程在内存当中的布局形式,帮助大家深刻理解线程
    2022-11-11
  • C语言中共享内存完整示例示例

    C语言中共享内存完整示例示例

    本文主要介绍了C语言中共享内存完整示例示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-11-11
  • C++面试题之结构体内存对齐计算问题总结大全

    C++面试题之结构体内存对齐计算问题总结大全

    这篇文章主要给大家总结了关于C++面试题中结构体内存对齐计算问题的相关资料,文中通过示例代码介绍的非常详细,通过这些介绍的内容对大家在面试C++工作的时候,会有一定的参考帮助,需要的朋友们下面随着小编来一起学习学习吧。
    2017-08-08
  • C++数据结构模板进阶的多方面分析

    C++数据结构模板进阶的多方面分析

    今天我要给大家介绍C++中的模板更深的一些知识。有关于非类型的模板参数和模板特化的一些知识,感兴趣的朋友快来看看吧
    2022-02-02
  • C语言实现简单通讯录

    C语言实现简单通讯录

    这篇文章主要为大家详细介绍了C语言实现简易通讯录,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-05-05

最新评论