C++标准库中时钟(Clock)

这段内容主要介绍了C++标准库中**时钟(Clock)**的概念和分类,以及它们在时间测量中的作用。以下是关键信息的解读:

一、时钟的核心特性

C++中的时钟是一个类,提供以下四个基本属性:

  1. 当前时间
    通过静态成员函数 now() 获取,返回类型为 time_point

    std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
    
  2. 时间表示类型
    通过 time_point 成员类型定义,通常是 std::chrono::time_point<Clock, Duration>

  3. 时钟精度(Tick Period)
    表示时钟的最小时间间隔,使用 std::ratio 模板定义。例如:

    • 每秒25次滴答:std::ratio<1,25>(40毫秒)
    • 每2.5秒一次滴答:std::ratio<5,2>(2.5秒)
  4. 是否为稳定时钟(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);  // 转换为字符串
    

四、时钟精度与实际行为

  1. 理论精度 vs 实际精度

    • 时钟的 period 定义理论最小间隔,但实际精度受硬件限制。
    • 例如,high_resolution_clockperiod 可能为 std::ratio<1, 1000000000>(纳秒),但实际可能只能达到微秒级。
  2. 非均匀滴答

    • 系统时钟的 now() 可能返回比之前更早的时间(如时间回拨)。
    • 稳定时钟保证 now() 单调递增,适合循环超时检测:
      auto deadline = std::chrono::steady_clock::now() + std::chrono::seconds(10);
      while (std::chrono::steady_clock::now() < deadline) {// 执行任务,不会因系统时间调整导致超时失效
      }
      

五、常见应用场景

  1. 超时控制

    // 使用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));
    }
    
  2. 性能测量

    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;
    
  3. 时间点转换

    // 系统时钟转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);
    

六、注意事项

  1. 避免混用时钟类型

    • 不同时钟的 time_point 不可直接比较,需通过 duration_cast 转换。
  2. 时钟选择原则

    • 需要真实时间(如文件时间戳)→ 使用 system_clock
    • 需要可靠时间间隔(如超时、耗时统计)→ 使用 steady_clock
    • 需要最高精度(如科学计算)→ 使用 high_resolution_clock
  3. 时钟实现差异

    • high_resolution_clock 可能是 system_clocksteady_clock 的别名,具体取决于平台。

七、总结

C++的时钟系统通过 system_clocksteady_clockhigh_resolution_clock 提供了灵活的时间测量能力:

  • 系统时钟:与现实时间同步,但可能非单调。
  • 稳定时钟:保证时间单调递增,适合测量时间间隔。
  • 高精度时钟:提供平台支持的最高精度。

合理选择时钟类型是编写可靠时间敏感代码的关键,特别是在超时控制、性能分析和分布式系统同步等场景中。

这段内容详细介绍了C++标准库中std::chrono::duration的核心概念、用法及应用场景,以下是结构化解读:

Duration

一、duration的基本概念

1. 模板定义与参数

std::chrono::duration<Rep, Period> 是表示时间间隔的类模板:

  • Rep:表示时间间隔的数值类型(如intdouble)。
  • 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定义示例
nanosecondsduration<int64_t, nano>10ns
microsecondsduration<int64_t, micro>100us
millisecondsduration<int64_t, milli>1000ms
secondsduration<int64_t>10s
minutesduration<int64_t, ratio<60>>5min
hoursduration<int64_t, ratio<3600>>24h

特点

  • 自动选择足够大的整数类型,支持表示超过500年的时间间隔。
  • 支持SI单位前缀(如attocentikilo等)。

三、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;
}

七、关键注意事项

  1. 精度与平台差异

    • 实际时钟精度可能低于duration理论精度(如系统仅支持毫秒级,nanoseconds会被舍入)。
  2. 时钟选择

    • 超时等待使用steady_clock(避免系统时钟调整影响):
      // 正确:使用steady_clock的duration
      std::this_thread::sleep_for(std::chrono::seconds(1));
      
  3. 类型安全

    • 不同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 通过模板设计提供了类型安全的时间间隔表示,结合预定义类型和字面值后缀,使代码更简洁易读。其核心优势在于:

  1. 类型安全:编译期检查时间单位,避免逻辑错误。
  2. 精确控制:支持从纳秒到小时的任意时间单位。
  3. 跨平台兼容:统一时间处理接口,屏蔽底层差异。

在多线程编程中,durationfuturethread 等组件配合,实现精准的超时控制和性能测量,是现代C++并发编程的基础工具之一。

C++ 时间点(time_point)详解:从概念到实践

一、时间点的基本定义与结构

std::chrono::time_point 是 C++ 标准库中表示时间点的类模板,它就像时间轴上的一个“坐标点”,其核心定义如下:

template <class Clock, class Duration>
class time_point;
  • 第一个模板参数(Clock):指定时间点所基于的时钟类型(如系统时钟 system_clock、高分辨率时钟 high_resolution_clock)。
  • 第二个模板参数(Duration):指定时间点的计量单位(如 secondsmilliseconds)。

核心概念——纪元(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;
二、时间点的核心操作:加减与计算间隔
  1. 时间点与时间段的加减
    时间点可以通过加减 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;
    }
    
  2. 时间点之间的差值计算
    同一时钟的两个时间点相减会得到它们的时间间隔(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++ 提供了三种主要时钟类型,它们与时间点的配合需注意:

  1. system_clock:系统实时时钟,可通过 to_time_t()from_time_t() 与日历时间转换。
  2. steady_clock:单调时钟,时间只会递增(即使系统时间被调整),适合测量时间间隔。
  3. 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 是未定义行为!
四、实际应用场景
  1. 任务超时控制
    在多线程编程中,等待线程时设置绝对超时时间:

    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 {// 超时处理}
    }
    
  2. 性能分析与日志记录
    在框架或库中记录关键流程的耗时:

    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_pointduration,开发者可以在程序中实现精确的时间测量、超时控制和性能分析,这在多线程编程、网络通信、游戏开发等场景中至关重要。

带超时机制的条件变量等待

代码功能概述

这段代码实现了一个带超时功能的条件变量等待机制,核心逻辑如下:

  • 定义全局变量:条件变量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
);
参数解析
  1. lk

    • 类型:std::unique_lock<std::mutex>&
    • 作用:必须持有互斥量m的锁,等待期间会释放锁,唤醒后重新获取。
  2. timeout_time

    • 类型:std::chrono::time_point<Clock, Duration>
    • 作用:绝对超时时间点,使用std::chrono的时间点类型表示。
    • 示例:std::chrono::steady_clock::now() + std::chrono::milliseconds(500)
返回值机制

wait_until返回std::cv_status枚举值,可能为:

  1. std::cv_status::timeout

    • 条件:等待直到超时时间点仍未收到通知。
    • 处理:代码中通过break退出循环。
  2. std::cv_status::no_timeout

    • 条件:在超时前收到条件变量通知。
    • 处理:继续循环检查done条件(可能因虚假唤醒导致)。

执行流程分析

  1. 超时时间计算
    使用std::chrono::steady_clock获取当前时间,加上500毫秒得到绝对超时时间点timeout

  2. 等待过程

    • wait_until释放lk的锁,将线程置于等待状态。
    • 当以下情况发生时,线程被唤醒并重新获取锁:
      • 其他线程调用cv.notify_one()cv.notify_all()
      • 系统时间到达timeout时间点(超时)
  3. 条件检查

    • 唤醒后检查返回值:
      • 若超时(timeout),break退出循环
      • 若非超时(no_timeout),继续检查done条件(处理虚假唤醒)
  4. 结果返回
    无论是否超时,最终返回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同步)导致的超时不准确。

典型应用场景

  1. 网络请求超时

    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;
    }
    
  2. 任务调度超时

    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函数通过绝对时间点实现精确超时控制,是条件变量在超时场景下的核心接口。其工作流程可概括为:

  1. 计算绝对超时时间点
  2. 释放锁并等待通知/超时
  3. 唤醒后重新获取锁并返回状态
  4. 结合循环处理虚假唤醒和超时逻辑

合理使用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; // 所有数据处理完毕,退出线程
}
  • 超时但未停止时,继续尝试获取数据
  • 当生产结束且队列为空时,消费者线程退出

执行流程说明

  1. 生产者线程

    • 依次生产5个数据项,每次生产后通知消费者
    • 生产完成后标记stop为true并通知所有消费者
  2. 消费者线程

    • 每次等待数据时设置1秒超时
    • 收到数据后处理,若超时则输出提示并继续尝试
    • stop为true且队列为空时,退出线程
  3. 超时场景

    • 当生产者生产速度较慢时,消费者会多次超时
    • 最终生产者完成生产后,消费者处理完剩余数据并退出

常见应用场景

  1. 网络通信

    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;
    }
    
  2. 任务调度系统

    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;
    }
    

关键注意事项

  1. 虚假唤醒处理

    • 始终使用循环检查条件,而非单次if判断
    • 即使收到通知,也可能因虚假唤醒导致条件未满足
  2. 时钟选择

    • 优先使用steady_clock进行超时计算
    • system_clock可能因时间调整导致超时不准确
  3. 超时后的资源处理

    • 超时后应处理未完成的操作
    • 避免因超时导致资源泄漏或逻辑错误

通过这个示例,可以掌握带超时机制的条件变量使用方法,这在需要避免线程无限阻塞的多线程应用中非常重要。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/912843.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/912843.shtml
英文地址,请注明出处:http://en.pswp.cn/news/912843.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

npm install安装不成功(node:32388)怎么解决?

如果在执行 npm install 时出现问题&#xff0c;尤其是 node:32388 相关的错误&#xff0c;这通常意味着某些依赖或配置出了问题。这里有一些常见的解决方法&#xff0c;你可以尝试&#xff1a; 1. 清除 npm 缓存 有时候&#xff0c;npm 缓存问题会导致安装失败。你可以清除 …

Ubuntu-18.04-bionic 的apt的/etc/apt/sources.list 更换国内镜像软件源 笔记250702

Ubuntu-18.04-bionic 的apt的/etc/apt/sources.list更换国内镜像软件源 笔记250702 为 Ubuntu 18.04 LTS&#xff08;代号 Bionic Beaver&#xff09;更换 /etc/apt/sources.list 为国内镜像源 备份/etc/apt/sources.list文件 sudo cp -a /etc/apt/sources.list /etc/apt/sou…

【运维系列】【ubuntu22.04】安装GitLab

一.下载安装文件 rootgitlab:~# wget https://packages.gitlab.com/gitlab/gitlab-ce/packages/el/9/gitlab-ce-17.4.0-ce.0.el9.x86_64.rpm二.执行安装脚本 2.1 先执行安装前的命令 rootgitlab:~# apt install -y perl-interpreter rootgitlab:~# apt install -y openssh-s…

Cisco ASA防火墙查看ACL的条目数量

这里显示的条目数量为ACE, ACE是啥&#xff1f; ACE全称&#xff1a; access-list entry ACE指的是ACL条目展开后的数量&#xff0c; 啥叫展开&#xff1f; 示例&#xff1a; access-list out-in extend permit tcp80&443 host 1.1.1.1 host 2.2.2.2这种配置是占1条&#…

npm install安装的node_modules是什么

node_modules 是一个由 npm&#xff08;Node Package Manager&#xff09;管理的文件夹&#xff0c;存放着你的 Node.js 项目中所有安装的依赖包。当你运行 npm install 时&#xff0c;npm 会根据你的项目中 package.json 文件中的依赖配置&#xff0c;下载并安装相应的包到 no…

【实时Linux实战系列】实时Linux项目的部署与维护

在实时 Linux 项目的开发过程中&#xff0c;开发阶段的工作仅仅是开始&#xff0c;生产环境中的部署与维护同样至关重要。实时 Linux 系统广泛应用于工业自动化、航空航天、智能交通等对实时性和稳定性要求极高的领域。例如&#xff0c;在工业自动化中&#xff0c;实时系统的部…

Go并发模式精要:掌握Goroutine与Channel的实战艺术

在现代软件开发中&#xff0c;有效利用并发能力已成为提升系统性能的关键。Go语言凭借其原生的Goroutine和Channel机制&#xff0c;为开发者提供了优雅的并发解决方案。本文将深入解析Go并发编程的核心模式与最佳实践。 一、并发基石&#xff1a;Goroutine与Channel // 轻量级…

第29篇:Linux审计系统深度解析:基于OpenEuler 24.03的实践指南

Linux审计系统深度解析&#xff1a;基于OpenEuler 24.03的实践指南 文章目录 Linux审计系统深度解析&#xff1a;基于OpenEuler 24.03的实践指南一、Linux审计系统核心概念与组件架构1.1 审计系统核心组件详解1. auditd守护进程&#xff1a;日志持久化引擎2. auditctl命令行工具…

Linux 启动过程流程图--ARM版

以下是ARM版本Linux启动过程的超详细树状图&#xff0c;涵盖硬件上电到应用程序交互的全流程&#xff0c;并包含关键函数调用链及源码位置&#xff0c;适用于系统开发与调试场景&#xff1a; ARM Linux启动全流程&#xff08;含函数调用链&#xff09; ARM Linux启动流程&…

NVMe高速传输之摆脱XDMA设计6之系统架构设计

结合目前应用需求&#xff0c;以及前面基础分析&#xff0c;确定IP应具有如下特色&#xff1a; &#xff08;1&#xff09; 通用性 前端数据采集系统基于 FPGA 开发。 一方面&#xff0c; 设备类型多&#xff0c; 使用的 FPGA型号各不相同&#xff0c; 需要实现的设计能够在多种…

Mac homebrew 安装教程

下载github安装包 https://github.com/Homebrew/brew/releases/tag/4.5.8 下载安装后 打开 安全里面允许安装&#xff0c;就可以直接使用了

stm32hal模块驱动(1)hpdl1414驱动

之前一直想用hpdl1414画一块手表&#xff0c;前面pcb测试板画完没空调试&#xff0c;最近刚好空出来时间&#xff0c;遂发下驱动。 这里简单赘述hpdl1414的驱动原理&#xff1a;D0-D6负责数据输入&#xff08;ascii表后7位&#xff09;&#xff0c;A0,A1负责更改hpdl1414模块显…

从代码学习深度强化学习 - TRPO PyTorch版

文章目录 前言核心工具函数广义优势估计 (Generalized Advantage Estimation, GAE)案例一:TRPO 解决离散动作问题 (CartPole-v1)1. 环境初始化2. 网络结构定义3. TRPO 智能体实现4. 训练与可视化5. 训练主程序与结果案例二:TRPO 解决连续动作问题 (Pendulum-v1)1. 环境与工具…

MySQL 升级到8.4版本的详细指南

本指南详细介绍了将 MySQL 升级到 8.4 版本的完整流程、注意事项和操作方法。 一、升级前准备 (3.1 Before You Begin) 在开始升级之前&#xff0c;必须仔细审阅本节信息并执行所有推荐的操作&#xff1a; 理解升级过程&#xff1a;了解升级期间可能发生的情况。请参阅第 3.4…

leetcode427.建立四叉树

区间x0到x1和区间y0到y1都是左闭右开的 解题基本思路是先判断当前矩阵是不是全0或全1&#xff0c;如果是就直接返回新建的一个节点值(矩阵的统一值&#xff0c;叶子节点&#xff09;,如果不是那就新建一个节点值&#xff0c;非叶并且左上右上左下右下四个方向上递归创建节点 /…

医学+AI教育实践!南医大探索数据挖掘人才培养,清华指导发布AI教育白皮书

教育数字化浪潮正以前所未有的力度重塑高等教育格局。今年4月&#xff0c;为贯彻落实《教育强国建设规划纲要&#xff08;2024—2035 年&#xff09;》&#xff0c;教育部等九部门印发《关于加快推进教育数字化的意见》&#xff0c;表明将持续推动“人工智能教育”全方位发展&a…

PDF处理控件Spire.PDF系列教程:如何使用C# 拆分 PDF 文件(完整指南)

PDF文件因其高度的跨平台兼容性和安全稳定的格式特点&#xff0c;广泛应用于企业文档管理和电子资料传输中。随着PDF文档页数和内容复杂度的增加&#xff0c;拆分PDF成为优化文档处理流程、提升办公效率的重要需求。通过编程方式实现PDF拆分&#xff0c;不仅能自动化处理海量文…

文心4.5开源模型部署实践

文心4.5开源模型部署实践 使用fastdeploy本地部署 执行命令&#xff1a; python -m fastdeploy.entrypoints.openai.api_server \--model baidu/ERNIE-4.5-21B-A3B-Paddle \--port 8180 \--metrics-port 8181 \--engine-worker-queue-port 8182 \--max-model-len 32768 \--m…

Python迭代器、生成器、闭包和装饰器(三器一包)

return、continue、break区别&#xff1a; return只能用在函数里面&#xff0c;表示从函数中返回&#xff0c;函数体内的后续任何代码都不执行continue只是跳出当前循环&#xff0c;进入下一循环break只是跳出全部循环&#xff0c;如果循环后面还有代码&#xff0c;会进行执行…

【Java】Maven

一.Maven简介 Maven的产生主要是为了解决Java项目中的两个问题&#xff1a; 1.依赖管理&#xff1a; 传统 Java 项目在引入第三方库时&#xff0c;需要手动下载 JAR 包并维护复杂的依赖关系。Maven 提供了统一的依赖管理机制&#xff0c;通过简单的配置即可自动从仓库下载并引…