std::thread未执行C++函数问题求助
Timer线程未执行程序即退出的原因分析
问题代码
Timer类实现
class Timer { std::atomic<bool> active{true}; public: void setInterval(auto function, int interval); void stop(); }; void Timer::setInterval(auto function, int interval) { active = true; std::thread t([=]() { while(active.load()) { std::this_thread::sleep_for(std::chrono::milliseconds(interval)); if(!active.load()) return; function(); } }); t.detach(); } void Timer::stop() { active = false; }
main函数调用代码
int main() { printf("start\n"); Timer* timer = new Timer(); timer->setInterval([&]() { std::cout << "hello" << std::endl; },1000); return 0; };
编译命令
/usr/bin/g++ -fdiagnostics-color=always -std=c++14 -pthread -g /home/vagrant/cpp/batch/main.cpp -o /home/vagrant/cpp/batch/main
核心原因
- main函数过早退出导致进程终止:main函数执行到
return 0时,整个进程会立即结束,进程内所有线程(包括通过detach()分离的线程)都会被操作系统强制终止。你的Timer线程启动后首先会执行1秒的sleep操作,还没等到执行function(),main函数已经完成执行并退出,进程随之销毁,所以hello完全没机会打印。 - 分离线程的特性:使用
detach()后的线程不再与主线程关联,进程结束时不会等待分离线程完成任何操作,直接回收所有资源。
修复方案
方案1:让main函数等待足够时间
最简单的临时解决方式是让main函数等待一段时间,给线程执行的机会:
int main() { printf("start\n"); Timer* timer = new Timer(); timer->setInterval([&]() { std::cout << "hello" << std::endl; },1000); // 等待2秒,让线程有机会执行两次输出 std::this_thread::sleep_for(std::chrono::milliseconds(2000)); timer->stop(); delete timer; return 0; };
方案2:改用可join的线程管理(更严谨)
避免使用detach(),而是在Timer类中保存线程对象,通过join()等待线程正常退出,同时利用析构函数确保资源正确释放:
#include <thread> #include <atomic> #include <chrono> #include <iostream> #include <cstdio> class Timer { std::atomic<bool> active{true}; std::thread worker_thread; // 保存线程对象 public: void setInterval(auto function, int interval); void stop(); ~Timer() { if (worker_thread.joinable()) { worker_thread.join(); } } }; void Timer::setInterval(auto function, int interval) { active = true; worker_thread = std::thread([=]() { while(active.load()) { std::this_thread::sleep_for(std::chrono::milliseconds(interval)); if(!active.load()) return; function(); } }); } void Timer::stop() { active = false; if (worker_thread.joinable()) { worker_thread.join(); } } int main() { printf("start\n"); Timer timer; timer.setInterval([]() { std::cout << "hello" << std::endl; },1000); // 等待2.5秒,观察输出 std::this_thread::sleep_for(std::chrono::milliseconds(2500)); timer.stop(); return 0; };
内容的提问来源于stack exchange,提问作者user63898
相关产品推荐
相关产品推荐

