【问题标题】:Sleep an Async Task休眠一个异步任务
【发布时间】:2017-08-22 12:27:53
【问题描述】:

在我的项目中,我需要每隔 n 秒轮询一些设备,然后休眠并永远继续。我创建了一个异步任务,启动为异步而不是std::thread。但是,如果我在异步任务中使用 std::this_thread::sleep_for() 并以异步方式启动,看起来它实际上阻塞了我的主线程? 以下程序永远输出“Inside Async..”,它从不打印“Main function”。

如果我使用std::thread(),而不是异步,它会正常工作。但我想使用异步任务,因为我不必像线程那样加入它并管理它的生命周期。

如何让异步任务休眠?

#include <iostream>
#include <future>
#include <thread>

int main() 
{
    std::async(std::launch::async,
    []()
    {
        while(true)
        {
            std::cout <<"Inside async.."<< std::endl;   
            std::this_thread::sleep_for(std::chrono::seconds(2));
        }
    });

    std::cout <<"Main function"<< std::endl;
    return 0;
}

【问题讨论】:

  • 如果你只是简单地分离一个线程,你“不必再加入它并管理它的生命周期”了。
  • 曾经有段时间我们为此使用了documentation
  • @samvar 如果您希望程序干净地终止,那么分离并不简单。

标签: c++ multithreading c++11 c++14 future


【解决方案1】:

std::async 返回一个 std::future 等待任务在其析构函数中完成。将std::future 保存在某处以延迟析构函数:

auto future = std::async(...).

【讨论】:

  • 这个,请注意 std:.async 并不是严格要求异步运行的(标准说“好像在一个新的执行线程中”... 好像,不管那是什么),所以睡在里面可能不是最好的主意。
【解决方案2】:

std::async 返回一个std::future,该std::future 立即被销毁(它是一个临时的,不会被 const 引用延长或移动到某个对象中)。

std::future 的析构函数阻塞直到std::future 呈现的异步结果完成。由于您的异步任务尚未完成,因此对 std::async 的调用将永远阻塞。

延长 future 的生命周期无济于事,因为它的析构函数会在某个时候阻塞,你的异步任务永远不会结束。在这里使用std::thread 似乎很合适。

事实上,我会建议你使用一些第三方定时器实现,因为你想要的是一个定期执行的异步任务。这非常适合计时器。

【讨论】:

  • 希望析构函数在某个时刻阻塞,通常在main退出之前。
  • @nwp 如果我不关心异步任务的结果,那你就别想阻塞了。
  • 我不确定标准对比主线程寿命更长的线程有何规定。我觉得这样不行。
  • 标准很明确,因为线程比 main 长是未定义的行为。你可以懈怠和祈祷,你可以有一个非干净的关闭,你可以在主要结束之前退出(我相信也未定义它对运行线程的作用)。或者您可以跟踪您的线程。跟踪线程并不难。
猜你喜欢
  • 1970-01-01
  • 2011-04-26
  • 1970-01-01
  • 2016-12-14
  • 1970-01-01
  • 2016-01-16
  • 1970-01-01
  • 2018-03-30
相关资源
最近更新 更多