我试图用标准环境实现计时器这里是我有一个代码:
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; }