You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

实现带Start/Stop功能的C++回调定时器求助

带停止功能的异步回调定时器实现

需要实现一个定时器类,核心需求如下:

  • 启动异步线程,在指定超时时间后执行预设的回调函数
  • 支持在超时前主动停止定时器,此时回调函数不会被执行

以下是完善后的实现代码:

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

class Timer 
{
public:
    Timer(size_t time_ms, const std::function<void(void)>& callback) : 
        time(std::chrono::milliseconds(time_ms)),
        callback(callback) {}

    ~Timer() 
    { 
        stop();
        if (started) 
        { 
            wait_thread.join(); 
            started = false; 
        } 
    }

    void stop()
    {
        stopped.store(true);
        cv.notify_one();
    }

    void start()
    {
        if (!started)
        {
            stopped.store(false);
            started = true;
            wait_thread = std::thread{ [this]() { wait_then_call(); } };
        }
        else
        {
            std::cout << "Thread " << wait_thread.get_id() << " 已启动!" << std::endl;
        }
    }

private:
    void wait_then_call()
    {
        std::unique_lock<std::mutex> lck(mtx);
        std::cout << "Thread " << wait_thread.get_id() << " 将在 " << time.count() / 1000 << " 秒后执行回调" << std::endl;
        // 等待超时或被唤醒
        cv.wait_for(lck, time, [this](){ return stopped.load(); });

        // 只有未被停止时才执行回调
        if (!stopped.load())
        {
            callback();
        }
        else
        {
            std::cout << "Thread " << wait_thread.get_id() << " 已取消,回调不执行" << std::endl;
        }
    }

    std::mutex mtx;
    std::condition_variable cv{};
    std::chrono::milliseconds time;
    std::function<void(void)> callback;
    std::thread wait_thread;
    bool started = false;
    std::atomic<bool> stopped = false; // 原子变量保证线程安全
};

关键改动说明

  • 添加std::atomic<bool> stopped:原子变量确保多线程环境下修改和读取的线程安全性,避免数据竞争
  • stop()方法:设置停止标志并唤醒等待中的线程,让定时器线程能立即退出等待逻辑
  • wait_then_call()方法:使用wait_for的第三个参数(谓词),等待超时或停止标志被设置;最后检查停止标志,仅当未停止时执行回调
  • 析构函数优化:先调用stop()确保线程能及时退出,再join线程,避免程序退出时的资源泄漏

测试示例

int main()
{
    auto f = []() {std::cout << "\n执行回调函数!" << std::endl; };

    Timer t1{ 3000, f };
    t1.start();

    Timer t2{ 10000, f };
    t2.start();

    // 主线程模拟其他任务,2秒后停止t2
    std::this_thread::sleep_for(std::chrono::seconds(2));
    t2.stop();

    // 等待t1执行完毕
    std::this_thread::sleep_for(std::chrono::seconds(2));
    return 0;
}

运行结果示例:

Thread 140702662397696 将在 3 秒后执行回调
Thread 140702653994880 将在 10 秒后执行回调
Thread 140702653994880 已取消,回调不执行

执行回调函数!

内容的提问来源于stack exchange,提问作者Dominic Sesto

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 19:53:14