C++定时器:Start与Stop功能正常,Restart无法终止旧线程
线程重启时无法终止旧线程的问题解决
问题核心在于:Restart()中调用Stop()后立刻执行Start(),此时旧线程还未完成退出逻辑,Start()就将running重新设为true,导致旧线程的wait_for条件检查失败,继续执行循环;同时新线程被创建,最终出现多线程并行运行的情况。而单独调用Stop()时,主线程会等待用户输入,这段时间足够旧线程响应通知并退出。
修复后的代码示例
#include <iostream> #include <thread> #include <condition_variable> #include <chrono> #include <atomic> using namespace std; atomic<bool> running = false; // 改用atomic保证线程安全读写 unsigned int interval = 5000; condition_variable cv_work; mutex mu_cv_work; thread worker_thread; // 保存线程对象,避免detach丢失线程控制权 void Start() { unique_lock<std::mutex> lock(mu_cv_work); if (running || worker_thread.joinable()) { return; // 避免重复启动线程 } running = true; lock.unlock(); worker_thread = thread([]{ cout << "new thread" << '\n'; while (running) { cout << "work..." << '\n'; unique_lock<std::mutex> lock(mu_cv_work); cout << "sleep" << '\n'; if (cv_work.wait_for(lock, chrono::milliseconds(interval), []{return !running;})) { cout << "exit thread" << '\n'; return; } cout << "done sleeping" << '\n'; } }); } void Stop() { unique_lock<std::mutex> lock(mu_cv_work); running = false; lock.unlock(); cv_work.notify_one(); if (worker_thread.joinable()) { worker_thread.join(); // 阻塞等待旧线程完全退出 worker_thread = thread(); // 重置线程对象,确保下次启动正常 } } void Restart() { Stop(); Start(); } int main() { Start(); cout << "press to Stop" << '\n'; cin.get(); Stop(); cout << "press to Start" << '\n'; cin.get(); Start(); cout << "press to Restart" << '\n'; cin.get(); Restart(); return 0; }
关键修改说明
- 原子变量存储运行状态:用
atomic<bool>替代普通bool,确保多线程对running的读写操作无数据竞争。 - 保留线程对象控制权:不再使用
detach(),而是用全局thread对象保存工作线程,通过join()等待线程完全退出。 - 避免重复启动:
Start()中增加检查逻辑,防止已有线程运行时重复创建新线程。 - 等待线程退出再继续:
Stop()中调用join()阻塞主线程,确保旧线程彻底终止后才返回,让Restart()中的Start()能安全创建新线程。
预期输出
press to Stop new thread work... sleep // KEY PRESS exit thread press to Start // KEY PRESS new thread work... sleep press to Restart // KEY PRESS exit thread new thread work... sleep done sleeping work... sleep
内容的提问来源于stack exchange,提问作者rozfet
相关产品推荐
相关产品推荐

