带reset功能的C++ Timer类问题:函数无延迟执行及reset失效
修复带Reset功能的Timer类问题
问题根源分析
- start后回调立即执行:原实现大概率在启动时直接调用了回调函数,而非通过延迟逻辑触发;或者定时器的等待逻辑错误(比如等待时长设为0)。
- reset方法无效:原实现未正确终止当前等待的定时器任务,也未重新启动新的延迟周期,导致原定时器仍会按原时间触发回调。
修复后的Timer类实现
#include <iostream> #include <functional> #include <thread> #include <chrono> #include <mutex> #include <condition_variable> class Timer { public: Timer(std::function<void()> func, std::chrono::milliseconds interval) : func_(std::move(func)), interval_(interval), running_(false), reset_flag_(false) {} ~Timer() { stop(); } void start() { std::lock_guard<std::mutex> lock(mtx_); if (running_) return; running_ = true; thread_ = std::thread(&Timer::timer_loop, this); } void stop() { std::lock_guard<std::mutex> lock(mtx_); running_ = false; reset_flag_ = true; cv_.notify_one(); if (thread_.joinable()) { thread_.join(); } } void reset() { std::lock_guard<std::mutex> lock(mtx_); reset_flag_ = true; cv_.notify_one(); } private: void timer_loop() { while (running_) { std::unique_lock<std::mutex> lock(mtx_); // 等待指定时长,或被reset/stop唤醒 auto wait_status = cv_.wait_for(lock, interval_, [this]() { return !running_ || reset_flag_; }); if (!running_) break; if (reset_flag_) { reset_flag_ = false; continue; // 重置后重新开始计时 } // 等待超时,触发回调 if (wait_status == std::cv_status::timeout) { func_(); } } } std::function<void()> func_; std::chrono::milliseconds interval_; std::thread thread_; std::mutex mtx_; std::condition_variable cv_; bool running_; bool reset_flag_; };
关键修复点说明
- 解决立即执行问题:通过
std::condition_variable::wait_for实现精准延迟,仅当等待周期结束(超时)时才执行回调函数,启动阶段不会直接调用。 - 解决reset无效问题:调用
reset()时设置重置标志并唤醒等待线程,线程被唤醒后会重置计时周期,重新开始等待,从而推迟回调的执行时间。
测试验证代码
int main() { Timer timer([](){ std::cout << "reached!" << std::endl; }, std::chrono::seconds(5)); timer.start(); // 每秒重置一次,理论上永远不会触发回调 while (true) { std::this_thread::sleep_for(std::chrono::seconds(1)); timer.reset(); std::cout << "reset timer" << std::endl; } timer.stop(); return 0; }
运行该代码后,只会持续输出reset timer,不会出现reached!,符合预期。
内容的提问来源于stack exchange,提问作者Babak.Abad
相关产品推荐
相关产品推荐

