导读:本期聚焦于小伙伴创作的《C++怎么实现一个计时器?多线程与高精度时间测量如何实现》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《C++怎么实现一个计时器?多线程与高精度时间测量如何实现》有用,将其分享出去将是对创作者最好的鼓励。

在C++开发中,计时器是很多场景下需要用到的功能,比如定时执行任务、周期性检测状态、超时控制等。要实现一个可靠的计时器,需要结合高精度时间测量和多线程技术,避免传统时间函数的精度不足和阻塞主线程的问题。

C++怎么实现一个计时器?多线程与高精度时间测量如何实现

高精度时间测量基础

C++11引入了<chrono>库,提供了跨平台的高精度时间测量能力,相比传统的<time.h>中的time函数,精度可以达到纳秒级别,非常适合计时器场景使用。

常用的chrono组件包括:

  • 时钟类:system_clock(系统时钟,可转换为时间戳)、steady_clock(单调时钟,不会被系统时间调整影响,适合计时)、high_resolution_clock(高精度时钟,通常是steady_clock的别名)
  • 时间间隔类:duration,用于表示一段时间,支持不同精度的时间单位转换
  • 时间点类:time_point,表示某个时刻

下面是获取当前时间并计算时间间隔的示例代码:

#include <iostream>
#include <chrono>
#include <thread>

int main() {
    // 获取开始时间点
    auto start = std::chrono::steady_clock::now();
    
    // 模拟耗时操作
    std::this_thread::sleep_for(std::chrono::milliseconds(100));
    
    // 获取结束时间点
    auto end = std::chrono::steady_clock::now();
    
    // 计算时间间隔,转换为毫秒
    auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
    std::cout << "耗时: " << duration.count() << " 毫秒" << std::endl;
    
    return 0;
}

单线程简单计时器实现

如果不需要同时处理其他逻辑,可以使用单线程+sleep的方式实现简单的计时器,但是这种方式会阻塞当前线程,不适合复杂场景。

#include <iostream>
#include <chrono>
#include <thread>
#include <functional>

// 简单计时器函数,interval为间隔毫秒数,callback为回调函数,times为执行次数,0表示无限执行
void simple_timer(int interval, std::function<void()> callback, int times = 0) {
    int count = 0;
    while (times == 0 || count < times) {
        std::this_thread::sleep_for(std::chrono::milliseconds(interval));
        callback();
        count++;
    }
}

// 测试回调函数
void test_callback() {
    auto now = std::chrono::system_clock::now();
    auto time_t_now = std::chrono::system_clock::to_time_t(now);
    std::cout << "定时任务执行,当前时间: " << std::ctime(&time_t_now) << std::endl;
}

int main() {
    // 每1000毫秒执行一次,总共执行3次
    simple_timer(1000, test_callback, 3);
    return 0;
}

多线程可控制计时器实现

实际开发中需要计时器在后台运行,不阻塞主线程,同时支持启动、停止、重启等操作,这时候就需要结合多线程来实现。

实现思路:

  • 创建一个工作线程,在线程中循环检查是否到达执行时间
  • 使用条件变量+互斥锁控制线程的等待和唤醒,避免忙等消耗CPU
  • 提供启动、停止、设置间隔等接口,保证线程安全

完整实现代码如下:

#include <iostream>
#include <chrono>
#include <thread>
#include <functional>
#include <mutex>
#include <condition_variable>
#include <atomic>

class Timer {
public:
    Timer() : is_running_(false), interval_ms_(0) {}
    
    ~Timer() {
        stop();
    }
    
    // 启动计时器,interval为间隔毫秒数,callback为回调函数
    void start(int interval, std::function<void()> callback) {
        // 如果已经在运行,先停止
        if (is_running_.load()) {
            stop();
        }
        
        interval_ms_ = interval;
        callback_ = callback;
        is_running_.store(true);
        
        // 启动工作线程
        worker_thread_ = std::thread(&Timer::worker_func, this);
    }
    
    // 停止计时器
    void stop() {
        if (is_running_.load()) {
            is_running_.store(false);
            // 唤醒等待的条件变量
            cv_.notify_one();
            if (worker_thread_.joinable()) {
                worker_thread_.join();
            }
        }
    }
    
    // 重启计时器,使用原来的间隔和回调
    void restart() {
        if (interval_ms_ > 0 && callback_) {
            start(interval_ms_, callback_);
        }
    }
    
private:
    // 工作线程函数
    void worker_func() {
        auto next_time = std::chrono::steady_clock::now();
        
        while (is_running_.load()) {
            next_time += std::chrono::milliseconds(interval_ms_);
            
            // 等待到下一个执行时间,或者被停止信号唤醒
            std::unique_lock<std::mutex> lock(mutex_);
            if (cv_.wait_until(lock, next_time, [this]() { return !is_running_.load(); })) {
                // 被唤醒且计时器已停止,退出循环
                break;
            }
            
            // 执行回调
            if (is_running_.load() && callback_) {
                callback_();
            }
        }
    }
    
private:
    std::atomic<bool> is_running_;          // 计时器是否运行中
    int interval_ms_;                        // 时间间隔,毫秒
    std::function<void()> callback_;        // 回调函数
    std::thread worker_thread_;              // 工作线程
    std::mutex mutex_;                       // 互斥锁
    std::condition_variable cv_;             // 条件变量
};

// 测试回调函数
void timer_callback() {
    auto now = std::chrono::steady_clock::now();
    auto duration = now.time_since_epoch();
    auto millis = std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();
    std::cout << "计时器触发,时间戳(毫秒): " << millis << std::endl;
}

int main() {
    Timer timer;
    
    // 启动计时器,每500毫秒执行一次
    timer.start(500, timer_callback);
    std::cout << "计时器已启动,运行3秒" << std::endl;
    
    // 主线程等待3秒
    std::this_thread::sleep_for(std::chrono::seconds(3));
    
    // 停止计时器
    timer.stop();
    std::cout << "计时器已停止" << std::endl;
    
    // 重启计时器,再运行2秒
    timer.restart();
    std::cout << "计时器已重启,运行2秒" << std::endl;
    std::this_thread::sleep_for(std::chrono::seconds(2));
    
    // 再次停止
    timer.stop();
    std::cout << "程序结束" << std::endl;
    
    return 0;
}

实现注意事项

  • 优先使用steady_clock进行计时,避免系统时间调整导致计时器执行异常
  • 多线程操作共享变量时,使用std::atomic或者互斥锁保证线程安全
  • 工作线程中使用条件变量的wait_until方法,既可以精准等待到指定时间,又可以在需要停止时及时唤醒,避免sleep无法中断的问题
  • 计时器析构时要确保工作线程已经退出,避免野引用问题
  • 如果回调函数执行时间较长,可能会影响下一次定时任务的触发时间,需要根据实际需求调整实现逻辑

适用场景扩展

上述实现的是周期性执行的计时器,如果需要实现单次延迟执行的计时器,只需要修改工作线程逻辑,执行一次回调后就退出即可。另外也可以扩展支持动态调整时间间隔、注册多个回调函数等功能,满足更复杂的业务需求。

C++Timer多线程高精度时间测量chrono修改时间:2026-06-29 20:36:24

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。