计时器挂起主线程

我试图用标准环境实现计时器这里是我有一个代码:

bool shutdownDetected = false; void signal_handler(const int sigid) { shutdownDetected = true; } int main(int argc, const char * argv[]) { signal(SIGTERM, (sig_t)signal_handler); std::async(std::launch::async, [&] () { std::this_thread::sleep_for( std::chrono::milliseconds{5000}); std::cout << "On TIMER!" << std::endl; } ); std::cout << "main function" << std::endl; while (!shutdownDetected) { } return EXIT_SUCCESS; } 

结果我在5秒后看到输出:

 // 5 seconds left On Timer main function 

但希望看到:

 main function // 5 seconds left On Timer 

似乎我的执行挂起主线程以及。 如何避免这一点?

你的std :: async命令返回一个std :: future,然后立即销毁。 问题是,未来的破坏涉及到“加入”你创建的线程,这意味着析构函数将等待直到线程自行结束,并且主线程中的代码执行不会提前,直到该进程完成。

简单的答案是将您的std :: async调用的结果分配给一个变量,并可能在您的循环中调用其get()成员函数来测试终止。

 auto t = std::async(std::launch::async, [&] () { std::this_thread::sleep_for( std::chrono::milliseconds{5000}); std::cout << "On TIMER!" << std::endl; } ); std::cout << "main function" << std::endl; t.get(); 
 std::async(std::launch::async, [&] () { std::this_thread::sleep_for( std::chrono::milliseconds{5000}); std::cout << "On TIMER!" << std::endl; } ); 

除非您将由std::async返回的std::future分配给一个变量并将其保留,否则不起作用。 我不知道这是为什么,显然是因为我不能去查它。 Vincent Savard做了,并且把我们与std::future的析构函数的文档联系了起来:

如果满足以下所有条件,则可能会阻塞:共享状态是通过调用std :: async创建的,共享状态尚未准备好,并且这是对共享状态的最后一个引用。

由于返回的std::future没有被分配给任何东西,它被立即销毁,并且析构函数阻塞直到完成。

我要去掉信号处理程序,因为它与问题无关。

 #include <iostream> #include <future> int main() { auto letMeLive = std::async(std::launch::async, [] () { std::this_thread::sleep_for( std::chrono::milliseconds{5000}); std::cout << "On TIMER!" << std::endl; } ); std::cout << "main function" << std::endl; letMeLive.wait(); // instead of the signal handler return EXIT_SUCCESS; }