把 500 和秒、毫秒混在同一个 int 里,很容易把单位用错。<chrono> 把数值和单位绑在类型上:500ms 与 2s 不是同一种类型,相加时由库换算。时长叫 duration,某一时刻叫 time_point。测循环耗时用单调时钟 steady_clock;打印墙钟时间用 system_clock。睡眠见线程。
duration 与字面量
常用别名有 seconds、milliseconds。500ms、2s 需要 using namespace std::chrono_literals;(C++14)。count() 只给出裸数字,打印时自己标明单位。
#include <chrono>
#include <iostream>
int main() {
using namespace std::chrono_literals;
auto wait = 500ms;
auto sec = 2s;
std::cout << wait.count() << "\n";
std::cout << sec.count() << "\n";
return 0;
}输出:
500
2时钟
测量代码耗时应优先 steady_clock,避免墙钟调整导致负间隔。
steady_clock:只往前走,适合测间隔、超时。system_clock:跟日期时间相关,适合日志;不要用来测很短的循环。high_resolution_clock:精度最高的别名,实现上可能就是上面二者之一。
两个时间点相减得到时长。换成微秒打印时用 duration_cast,因为不同单位的 duration 不能随便窄化。转换时向零截断。不同时钟上的时间点不能直接相减。
auto t0 = std::chrono::steady_clock::now();
// ... 要测的代码 ...
auto t1 = std::chrono::steady_clock::now();
auto us = std::chrono::duration_cast<std::chrono::microseconds>(t1 - t0);
std::cout << us.count() << " us\n";循环耗时随机器变化,本站不提供该段的运行按钮。本地可自行包一层循环验证。
与线程睡眠
#include <chrono>
#include <thread>
void pause() {
using namespace std::chrono_literals;
std::this_thread::sleep_for(100ms);
}sleep_for、sleep_until 都吃 chrono 类型。下一节的并发原语共用这一套时间表示。
本节说明了 chrono 的时长、时钟与转换方式。下一节介绍线程与互斥量:并发执行与数据竞争防护入门。