C++标准库中时钟(Clock)
这段内容主要介绍了C++标准库中**时钟(Clock)**的概念和分类,以及它们在时间测量中的作用。以下是关键信息的解读:
一、时钟的核心特性
C++中的时钟是一个类,提供以下四个基本属性:
-
当前时间
通过静态成员函数now()
获取,返回类型为time_point
。std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
-
时间表示类型
通过time_point
成员类型定义,通常是std::chrono::time_point<Clock, Duration>
。 -
时钟精度(Tick Period)
表示时钟的最小时间间隔,使用std::ratio
模板定义。例如:- 每秒25次滴答:
std::ratio<1,25>
(40毫秒) - 每2.5秒一次滴答:
std::ratio<5,2>
(2.5秒)
- 每秒25次滴答:
-
是否为稳定时钟(Steady Clock)
通过静态成员is_steady
判断,若为true
表示时钟不可调,适用于测量时间间隔。
二、三种标准时钟
时钟类型 | 特性 | 典型用途 |
---|---|---|
std::chrono::system_clock | 系统实时时钟,可调整(如NTP同步)is_steady = false 支持与 time_t 互转 | 日期时间显示、文件时间戳 |
std::chrono::steady_clock | 稳定时钟,不可调整is_steady = true 保证单调递增 | 超时计算、性能测量 |
std::chrono::high_resolution_clock | 最高精度时钟(可能是其他时钟的别名) tick period最小 | 需要高精度的时间测量 |
三、稳定时钟 vs 系统时钟
1. 稳定时钟(Steady Clock)
- 特性:
- 时间单调递增,不会因系统时间调整而回退。
- 适用于测量相对时间间隔(如超时、耗时统计)。
- 示例:
auto start = std::chrono::steady_clock::now(); // 执行耗时操作 auto end = std::chrono::steady_clock::now(); auto duration = end - start; // 可靠的时间间隔
2. 系统时钟(System Clock)
- 特性:
- 反映真实世界时间,但可能因调整(如夏令时、NTP同步)而回退。
- 支持与
time_t
互转,便于格式化输出。
- 示例:
auto now = std::chrono::system_clock::now(); std::time_t t = std::chrono::system_clock::to_time_t(now); std::cout << "Current time: " << std::ctime(&t); // 转换为字符串
四、时钟精度与实际行为
-
理论精度 vs 实际精度
- 时钟的
period
定义理论最小间隔,但实际精度受硬件限制。 - 例如,
high_resolution_clock
的period
可能为std::ratio<1, 1000000000>
(纳秒),但实际可能只能达到微秒级。
- 时钟的
-
非均匀滴答
- 系统时钟的
now()
可能返回比之前更早的时间(如时间回拨)。 - 稳定时钟保证
now()
单调递增,适合循环超时检测:auto deadline = std::chrono::steady_clock::now() + std::chrono::seconds(10); while (std::chrono::steady_clock::now() < deadline) {// 执行任务,不会因系统时间调整导致超时失效 }
- 系统时钟的
五、常见应用场景
-
超时控制
// 使用steady_clock计算超时点 auto timeout = std::chrono::steady_clock::now() + std::chrono::milliseconds(500);// 等待操作,检查是否超时 while (condition_not_met()) {if (std::chrono::steady_clock::now() > timeout) {throw std::runtime_error("Operation timed out");}std::this_thread::sleep_for(std::chrono::milliseconds(10)); }
-
性能测量
auto start = std::chrono::high_resolution_clock::now(); expensive_operation(); auto end = std::chrono::high_resolution_clock::now(); std::cout << "Operation took " << std::chrono::duration<double, std::milli>(end - start).count()<< " ms" << std::endl;
-
时间点转换
// 系统时钟转time_t std::time_t current_time = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());// 从time_t构造时间点 std::chrono::system_clock::time_point tp = std::chrono::system_clock::from_time_t(current_time);
六、注意事项
-
避免混用时钟类型
- 不同时钟的
time_point
不可直接比较,需通过duration_cast
转换。
- 不同时钟的
-
时钟选择原则
- 需要真实时间(如文件时间戳)→ 使用
system_clock
。 - 需要可靠时间间隔(如超时、耗时统计)→ 使用
steady_clock
。 - 需要最高精度(如科学计算)→ 使用
high_resolution_clock
。
- 需要真实时间(如文件时间戳)→ 使用
-
时钟实现差异
high_resolution_clock
可能是system_clock
或steady_clock
的别名,具体取决于平台。
七、总结
C++的时钟系统通过 system_clock
、steady_clock
和 high_resolution_clock
提供了灵活的时间测量能力:
- 系统时钟:与现实时间同步,但可能非单调。
- 稳定时钟:保证时间单调递增,适合测量时间间隔。
- 高精度时钟:提供平台支持的最高精度。
合理选择时钟类型是编写可靠时间敏感代码的关键,特别是在超时控制、性能分析和分布式系统同步等场景中。
这段内容详细介绍了C++标准库中std::chrono::duration
的核心概念、用法及应用场景,以下是结构化解读:
Duration
一、duration
的基本概念
1. 模板定义与参数
std::chrono::duration<Rep, Period>
是表示时间间隔的类模板:
Rep
:表示时间间隔的数值类型(如int
、double
)。Period
:时间单位的比例(如std::ratio<60,1>
表示1分钟=60秒)。
2. 核心特性
// 示例:定义10分钟的duration
std::chrono::duration<int, std::ratio<60, 1>> ten_minutes(10);// 等价于预定义类型
std::chrono::minutes ten_minutes(10);
二、预定义时间单位
类型别名 | 对应duration 定义 | 示例 |
---|---|---|
nanoseconds | duration<int64_t, nano> | 10ns |
microseconds | duration<int64_t, micro> | 100us |
milliseconds | duration<int64_t, milli> | 1000ms |
seconds | duration<int64_t> | 10s |
minutes | duration<int64_t, ratio<60>> | 5min |
hours | duration<int64_t, ratio<3600>> | 24h |
特点:
- 自动选择足够大的整数类型,支持表示超过500年的时间间隔。
- 支持SI单位前缀(如
atto
、centi
、kilo
等)。
三、C++14时间字面值后缀
1. 整数字面值
using namespace std::chrono_literals;auto one_day = 24h; // hours(24)
auto half_hour = 30min; // minutes(30)
auto max_delay = 500ms; // milliseconds(500)
auto precision = 100ns; // nanoseconds(100)
2. 浮点数支持
auto float_duration = 2.5min; // duration<double, ratio<60>>
auto precise = 0.5ms; // duration<double, milli>
注意:浮点数字面值会使用未指定的浮点类型,若需精确控制类型,需手动构造:
std::chrono::duration<float, std::milli> precise(0.5f); // 显式指定float类型
四、时间单位转换
1. 隐式转换(无精度损失)
std::chrono::hours h(1);
std::chrono::minutes m = h; // 隐式转换:1h = 60min
2. 显式转换(可能截断)
std::chrono::milliseconds ms(54802);
std::chrono::seconds s = std::chrono::duration_cast<std::chrono::seconds>(ms);
// s.count() = 54(54802ms = 54s + 802ms,截断取整)
3. 四舍五入转换
std::chrono::milliseconds ms(54802);
std::chrono::seconds s = std::chrono::round<std::chrono::seconds>(ms);
// s.count() = 55(54802ms ≈ 55s)
五、算术操作
1. 基本运算
std::chrono::seconds a(10), b(20), c;c = a + b; // 30s
c = b - a; // 10s
c = a * 2; // 20s
c = b / 2; // 10s
2. 复合运算
std::chrono::minutes m(1);
m += std::chrono::seconds(30); // 1min30s
m -= std::chrono::seconds(60); // 30s
m *= 2; // 1min
3. 比较运算
std::chrono::seconds a(10), b(20);
bool is_less = a < b; // true
bool is_equal = a == b; // false
六、在异步操作中的应用
1. 超时控制
std::future<int> fut = std::async([] { std::this_thread::sleep_for(std::chrono::seconds(1));return 42;
});// 等待35毫秒
if (fut.wait_for(std::chrono::milliseconds(35)) == std::future_status::ready) {std::cout << "Result: " << fut.get() << std::endl;
} else {std::cout << "Timeout!" << std::endl;
}
2. 状态检查
std::promise<void> prom;
std::future<void> fut = prom.get_future();// 循环检查状态,总超时1秒
auto deadline = std::chrono::steady_clock::now() + std::chrono::seconds(1);
while (std::chrono::steady_clock::now() < deadline) {if (fut.wait_for(std::chrono::milliseconds(100)) == std::future_status::ready) {break;}std::cout << "Waiting..." << std::endl;
}
七、关键注意事项
-
精度与平台差异
- 实际时钟精度可能低于
duration
理论精度(如系统仅支持毫秒级,nanoseconds
会被舍入)。
- 实际时钟精度可能低于
-
时钟选择
- 超时等待使用
steady_clock
(避免系统时钟调整影响):// 正确:使用steady_clock的duration std::this_thread::sleep_for(std::chrono::seconds(1));
- 超时等待使用
-
类型安全
- 不同
duration
不可直接运算,需转换:std::chrono::seconds s(1); std::chrono::milliseconds ms = s; // 正确:seconds→milliseconds // std::chrono::minutes m = s; 错误:需显式转换
- 不同
八、典型应用场景
1. 性能测量
auto start = std::chrono::high_resolution_clock::now();
do_expensive_work();
auto end = std::chrono::high_resolution_clock::now();auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
std::cout << "Work took " << duration.count() << " ms" << std::endl;
2. 心跳检测
auto last_heartbeat = std::chrono::steady_clock::now();while (is_running()) {do_work();if (std::chrono::steady_clock::now() - last_heartbeat > std::chrono::seconds(5)) {send_heartbeat();last_heartbeat = std::chrono::steady_clock::now();}
}
九、总结
std::chrono::duration
通过模板设计提供了类型安全的时间间隔表示,结合预定义类型和字面值后缀,使代码更简洁易读。其核心优势在于:
- 类型安全:编译期检查时间单位,避免逻辑错误。
- 精确控制:支持从纳秒到小时的任意时间单位。
- 跨平台兼容:统一时间处理接口,屏蔽底层差异。
在多线程编程中,duration
与 future
、thread
等组件配合,实现精准的超时控制和性能测量,是现代C++并发编程的基础工具之一。
C++ 时间点(time_point)详解:从概念到实践
一、时间点的基本定义与结构
std::chrono::time_point
是 C++ 标准库中表示时间点的类模板,它就像时间轴上的一个“坐标点”,其核心定义如下:
template <class Clock, class Duration>
class time_point;
- 第一个模板参数(Clock):指定时间点所基于的时钟类型(如系统时钟
system_clock
、高分辨率时钟high_resolution_clock
)。 - 第二个模板参数(Duration):指定时间点的计量单位(如
seconds
、milliseconds
)。
核心概念——纪元(Epoch):
每个时钟都有一个“纪元”作为时间计算的起点(类似数轴的原点)。例如:
system_clock
的纪元通常是 1970-01-01 00:00:00(Unix 时间戳起点)。high_resolution_clock
的纪元可能是程序启动的瞬间。
虽然无法直接查询纪元的具体时间,但可以通过time_since_epoch()
方法获取时间点距离纪元的时间间隔:
std::chrono::time_point<std::chrono::system_clock> now = std::chrono::system_clock::now();
std::chrono::seconds since_epoch = std::chrono::duration_cast<std::chrono::seconds>(now.time_since_epoch());
std::cout << "距离纪元过去了:" << since_epoch.count() << " 秒" << std::endl;
二、时间点的核心操作:加减与计算间隔
-
时间点与时间段的加减
时间点可以通过加减duration
来获取未来或过去的时间点:// 获取当前高分辨率时间点 auto now = std::chrono::high_resolution_clock::now(); // 计算 500 纳秒后的时间点 auto future = now + std::chrono::nanoseconds(500); // 计算 10 秒前的时间点 auto past = now - std::chrono::seconds(10);
这种操作在设置超时场景中非常实用,例如:
std::future<int> result = std::async(doTask); auto timeout = std::chrono::system_clock::now() + std::chrono::seconds(5); // 5秒后超时 while (result.wait_until(timeout) != std::future_status::ready) {std::cout << "任务未完成,继续等待..." << std::endl; }
-
时间点之间的差值计算
同一时钟的两个时间点相减会得到它们的时间间隔(duration
类型),这是性能分析的常用手段:// 测量函数执行时间 auto start = std::chrono::high_resolution_clock::now();// 执行需要计时的代码 for (int i = 0; i < 1000000; i++) {// 复杂计算... }auto end = std::chrono::high_resolution_clock::now();// 计算时间差并转换为秒 auto duration = std::chrono::duration<double, std::chrono::seconds>(end - start); std::cout << "循环执行耗时:" << duration.count() << " 秒" << std::endl;
上述代码中,
end - start
的结果是duration<long, nano>
(纳秒级),通过duration_cast
或直接构造指定单位的duration
可以转换为秒、毫秒等单位。
三、时钟类型与时间点的兼容性
C++ 提供了三种主要时钟类型,它们与时间点的配合需注意:
system_clock
:系统实时时钟,可通过to_time_t()
和from_time_t()
与日历时间转换。steady_clock
:单调时钟,时间只会递增(即使系统时间被调整),适合测量时间间隔。high_resolution_clock
:高精度时钟,通常是steady_clock
的特化版本,适合需要纳秒级精度的场景。
重要注意事项:只有基于同一时钟的时间点才能直接相减,不同时钟的时间点无法直接比较,因为它们的纪元可能不同。例如:
auto sys_time = std::chrono::system_clock::now();
auto steady_time = std::chrono::steady_clock::now();
// sys_time - steady_time 是未定义行为!
四、实际应用场景
-
任务超时控制
在多线程编程中,等待线程时设置绝对超时时间:std::mutex mtx; std::unique_lock<std::mutex> lock(mtx, std::try_to_lock); if (!lock.owns_lock()) {// 尝试加锁失败,设置 100 毫秒后再次尝试auto timeout = std::chrono::steady_clock::now() + std::chrono::milliseconds(100);if (lock.try_lock_until(timeout)) {// 成功获取锁} else {// 超时处理} }
-
性能分析与日志记录
在框架或库中记录关键流程的耗时:class PerformanceLogger { private:std::chrono::time_point<std::chrono::high_resolution_clock> start_time;public:void start() {start_time = std::chrono::high_resolution_clock::now();}double endAndGetMs() {auto end = std::chrono::high_resolution_clock::now();auto duration = std::chrono::duration<double, std::chrono::milliseconds>(end - start_time);return duration.count();} };// 使用示例 PerformanceLogger logger; logger.start(); processBigData(); std::cout << "数据处理耗时:" << logger.endAndGetMs() << " 毫秒" << std::endl;
五、总结:duration 与 time_point 的协作关系
duration
表示“时间段”(如 5 秒、100 毫秒),是相对概念。time_point
表示“时间点”(如 2025-07-02 15:30:00),是绝对概念(基于时钟纪元)。- 两者结合使用可以完成从“计算时间间隔”到“设置绝对超时”的各种时间操作,是 C++ 时间处理体系的核心组件。
通过合理运用 time_point
和 duration
,开发者可以在程序中实现精确的时间测量、超时控制和性能分析,这在多线程编程、网络通信、游戏开发等场景中至关重要。
带超时机制的条件变量等待
代码功能概述
这段代码实现了一个带超时功能的条件变量等待机制,核心逻辑如下:
- 定义全局变量:条件变量
cv
、状态标志done
、互斥量m
wait_loop()
函数实现了一个等待循环,最多等待500毫秒- 超时判断:使用
std::chrono::steady_clock
计算绝对超时时间点 - 循环检查:当条件变量通知或超时发生时退出循环
#include <condition_variable>
#include <mutex>
#include <chrono>std::condition_variable cv;
bool done;
std::mutex m;bool wait_loop()
{// 计算绝对超时时间点:当前时间 + 500毫秒auto const timeout = std::chrono::steady_clock::now() + std::chrono::milliseconds(500);std::unique_lock<std::mutex> lk(m);while (!done) {// 等待条件变量通知或超时if (cv.wait_until(lk, timeout) == std::cv_status::timeout) {break; // 超时则退出循环}}return done; // 返回最终的done状态
}
wait_until
函数详解
函数签名
template <class Rep, class Period, class Clock>
std::cv_status wait_until(std::unique_lock<std::mutex>& lk,const std::chrono::time_point<Clock, std::chrono::duration<Rep, Period>>& timeout_time
);
参数解析
-
lk
:- 类型:
std::unique_lock<std::mutex>&
- 作用:必须持有互斥量
m
的锁,等待期间会释放锁,唤醒后重新获取。
- 类型:
-
timeout_time
:- 类型:
std::chrono::time_point<Clock, Duration>
- 作用:绝对超时时间点,使用
std::chrono
的时间点类型表示。 - 示例:
std::chrono::steady_clock::now() + std::chrono::milliseconds(500)
- 类型:
返回值机制
wait_until
返回std::cv_status
枚举值,可能为:
-
std::cv_status::timeout
:- 条件:等待直到超时时间点仍未收到通知。
- 处理:代码中通过
break
退出循环。
-
std::cv_status::no_timeout
:- 条件:在超时前收到条件变量通知。
- 处理:继续循环检查
done
条件(可能因虚假唤醒导致)。
执行流程分析
-
超时时间计算:
使用std::chrono::steady_clock
获取当前时间,加上500毫秒得到绝对超时时间点timeout
。 -
等待过程:
wait_until
释放lk
的锁,将线程置于等待状态。- 当以下情况发生时,线程被唤醒并重新获取锁:
- 其他线程调用
cv.notify_one()
或cv.notify_all()
- 系统时间到达
timeout
时间点(超时)
- 其他线程调用
-
条件检查:
- 唤醒后检查返回值:
- 若超时(
timeout
),break退出循环 - 若非超时(
no_timeout
),继续检查done
条件(处理虚假唤醒)
- 若超时(
- 唤醒后检查返回值:
-
结果返回:
无论是否超时,最终返回done
的当前状态。
关键技术点
1. 绝对时间 vs 相对时间
- 绝对时间:
wait_until
使用绝对时间点(如2025-07-02 15:30:00.500
),适合精确控制超时截止时间。 - 相对时间:
wait_for
使用时间段(如500ms
),适合设置相对等待时长。
2. 虚假唤醒处理
- 虽然代码中使用
while (!done)
循环,但超时后直接break,可能存在隐患:
更安全的做法是超时后仍检查// 改进版:超时后继续检查条件 while (!done) {if (cv.wait_until(lk, timeout) == std::cv_status::timeout) {break;} }
done
状态,避免因虚假唤醒导致提前退出。
3. 时钟选择
- 使用
std::chrono::steady_clock
:
确保时间单调递增,避免系统时钟调整(如NTP同步)导致的超时不准确。
典型应用场景
-
网络请求超时:
bool receive_data(timeout_ms) {bool data_ready = false;{std::unique_lock lk(mutex);auto timeout = std::chrono::steady_clock::now() + std::chrono::milliseconds(timeout_ms);while (!data_ready) {if (cv.wait_until(lk, timeout) == std::cv_status::timeout) {break;}}}return data_ready; }
-
任务调度超时:
bool wait_for_task_completion(int task_id, int timeout_seconds) {auto timeout = std::chrono::steady_clock::now() + std::chrono::seconds(timeout_seconds);std::unique_lock lk(mutex);while (tasks[task_id].status != completed) {if (cv.wait_until(lk, timeout) == std::cv_status::timeout) {return false; // 任务超时}}return true; }
总结
wait_until
函数通过绝对时间点实现精确超时控制,是条件变量在超时场景下的核心接口。其工作流程可概括为:
- 计算绝对超时时间点
- 释放锁并等待通知/超时
- 唤醒后重新获取锁并返回状态
- 结合循环处理虚假唤醒和超时逻辑
合理使用wait_until
能有效避免线程无限阻塞,是多线程编程中超时控制的关键机制。
带超时机制的条件变量等待示例:生产者-消费者模型
下面是一个使用条件变量超时机制的完整示例,实现了带超时的生产者-消费者模式。这个示例中,消费者线程会等待生产者提供数据,但设置了超时时间,避免无限阻塞。
#include<iostream>
#include<mutex>
#include<thread>
#include<chrono>
#include<condition_variable>
#include<queue>//the shared resource
bool done = false;
std::mutex mtx;
std::condition_variable cv;
std::queue<int> data_queue;//producer thread function
void producer()
{for (int i = 0; i < 5; i++){std::string data = "Data "+ std::to_string(i);{std::lock_guard<std::mutex> lock(mtx);data_queue.push(i);std::cout << "Produced: " << data << std::endl;}cv.notify_one(); // Notify the consumer that data is availablestd::this_thread::sleep_for(std::chrono::milliseconds(300)); // Simulate work}// Signal that production is done{std::lock_guard<std::mutex> lock(mtx);done = true;}cv.notify_one(); // Notify the consumer that no more data is available
}//consumer thread function
void consumer(int id)
{while (true){std::unique_lock<std::mutex> lock(mtx);//calculate the timeout point : the current time plus 1 secondauto timeout_point = std::chrono::steady_clock::now() + std::chrono::seconds(1);// Wait for data or timeout, use the loop to handle spurious wake-upswhile (data_queue.empty() && !done){if (cv.wait_until(lock, timeout_point) == std::cv_status::timeout){std::cout << "Consumer " << id << " timed out waiting for data." << std::endl;break;//timeout, exit the loop}}// Check if we have been signaled to done or if the queue is empty//when the production has not finished yet, continue to wait for dataif (!done && data_queue.empty()){continue;}//If we have been signaled to done and the queue is empty, exit the loopif (done && data_queue.empty()){std::cout<<" All data consumed by consumer "<<id<<std::endl;break;}// Consume dataint data = data_queue.front();data_queue.pop();std::string data_str = "Data "+std::to_string(data);std::cout << "Consumed by consumer " << id << ": " << data_str << std::endl;// Simulate processing timestd::this_thread::sleep_for(std::chrono::milliseconds(500));}
}int main()
{// Create and start the producer threadstd::thread prod_thread(producer);// Create and start the consumer threadsstd::thread cons_thread1(consumer, 1);std::thread cons_thread2(consumer, 2);// Wait for the threads to finishprod_thread.join();cons_thread1.join();cons_thread2.join();return 0;
}
代码解析:超时机制的关键部分
1. 超时时间计算
auto timeout = std::chrono::steady_clock::now() + std::chrono::seconds(1);
- 使用
steady_clock
确保时间单调递增,避免系统时钟调整导致的超时不准确 - 设置1秒的超时时间,可根据需求调整
2. 带超时的条件变量等待
while (data_queue.empty() && !stop) {if (cv.wait_until(lock, timeout) == std::cv_status::timeout) {std::cout << "Consumer " << id << ": Timeout, no data received" << std::endl;break;}
}
- 使用
wait_until
等待条件变量通知或超时 - 返回
cv_status::timeout
表示等待超时 - 外层循环处理虚假唤醒(即使收到通知,也需重新检查条件)
3. 超时后的逻辑处理
if (data_queue.empty() && !stop) {continue; // 超时但未停止,继续下一次循环
}if (stop && data_queue.empty()) {break; // 所有数据处理完毕,退出线程
}
- 超时但未停止时,继续尝试获取数据
- 当生产结束且队列为空时,消费者线程退出
执行流程说明
-
生产者线程:
- 依次生产5个数据项,每次生产后通知消费者
- 生产完成后标记
stop
为true并通知所有消费者
-
消费者线程:
- 每次等待数据时设置1秒超时
- 收到数据后处理,若超时则输出提示并继续尝试
- 当
stop
为true且队列为空时,退出线程
-
超时场景:
- 当生产者生产速度较慢时,消费者会多次超时
- 最终生产者完成生产后,消费者处理完剩余数据并退出
常见应用场景
-
网络通信:
bool receive_data(int socket, std::vector<char>& buffer, int timeout_ms) {// 设置超时时间auto timeout = std::chrono::steady_clock::now() + std::chrono::milliseconds(timeout_ms);std::unique_lock<std::mutex> lock(mutex);while (buffer.empty()) {if (cv.wait_until(lock, timeout) == std::cv_status::timeout) {return false; // 接收超时}}// 处理接收到的数据return true; }
-
任务调度系统:
bool wait_for_task(int task_id, int timeout_seconds) {auto timeout = std::chrono::steady_clock::now() + std::chrono::seconds(timeout_seconds);std::unique_lock<std::mutex> lock(mutex);while (tasks[task_id].status == TaskStatus::PENDING) {if (cv.wait_until(lock, timeout) == std::cv_status::timeout) {return false; // 任务执行超时}}return tasks[task_id].status == TaskStatus::COMPLETED; }
关键注意事项
-
虚假唤醒处理:
- 始终使用循环检查条件,而非单次
if
判断 - 即使收到通知,也可能因虚假唤醒导致条件未满足
- 始终使用循环检查条件,而非单次
-
时钟选择:
- 优先使用
steady_clock
进行超时计算 system_clock
可能因时间调整导致超时不准确
- 优先使用
-
超时后的资源处理:
- 超时后应处理未完成的操作
- 避免因超时导致资源泄漏或逻辑错误
通过这个示例,可以掌握带超时机制的条件变量使用方法,这在需要避免线程无限阻塞的多线程应用中非常重要。