计时器挂起主线程

时间:2016-11-24 20:17:20

标签: c++ linux macos unix std

我正在尝试使用标准环境实现计时器 这是我的代码:

// 5 seconds left
On Timer
main function

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

main function
// 5 seconds left
On Timer

但希望看到:

{{1}}

似乎我的实现也挂起了主线程。怎么避免这个?

2 个答案:

答案 0 :(得分:3)

你的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();

答案 1 :(得分:3)

std::async(std::launch::async, [&] () {
        std::this_thread::sleep_for( std::chrono::milliseconds{5000});
        std::cout << "On TIMER!" << std::endl;
    } );

除非您将std::future返回的std::async分配给变量并保留它,否则无效。我不知道为什么会这样,显然是因为我不敢去查阅它。文森特萨瓦德做了,并将我们与destructor for 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;
}