如何检查 std::async 任务是不是完成?

Posted

技术标签:

【中文标题】如何检查 std::async 任务是不是完成?【英文标题】:How to check if a std::async task is finished?如何检查 std::async 任务是否完成? 【发布时间】:2013-01-11 21:42:20 【问题描述】:

在我的图形应用程序中,我想在另一个线程中生成批处理网格。因此我使用std::async异步调用成员函数。

task = async(launch::async, &Class::Meshing, this, Data(...));

在我的更新循环中,我尝试检查线程是否准备好。如果是,我会将网格发送到视频卡并开始下一个线程。如果没有,我将跳过这些操作。

#include <future>
using namespace std;

class Class

public:
    void Update()
    
        if(task.finished()) // this method does not exist
        
            Data data = task.get();
            // ...
            task = async(launch::async, &Class::Meshing, this, Data(/* ... */));
        
    

private:
    struct Data
    
        // ...
    ;
    future<Data> task;
    Data Meshing(Data data)
    
        // ...
    
;

如何检查异步线程是否完成而不卡在更新函数中?

【问题讨论】:

我认为最接近的近似值是使用 std::future::wait_for 并以您可以管理的最短持续时间。 看来标准的future 没有继承Boost future is_ready 的成员函数,真可惜…… 我真的会推荐 this video Herb Sutter 介绍异步期货现在所处的位置、它们的局限性以及克服它们的一些可能方法。 @SeanCline:我想指出 boost::future 已经实现了其中的一些扩展,例如 wait_for_anywait_for_all。我们只缺少then... @ronag:你让我想到我们已经有了这些......是的,我们缺少 then 及其派生的 【参考方案1】:

使用future::wait_for()。你可以指定一个超时时间,然后得到一个状态码。

示例:

task.wait_for(std::chrono::seconds(1));

这将返回future_status::readyfuture_status::deferredfuture_status::timeout,以便您了解操作的状态。您还可以将超时时间指定为 0,以使检查尽快立即返回

【讨论】:

就是尽量接近,等待0秒,但不保证不会阻塞…… 继续阅读... “由于调度或资源争用延迟,此函数可能会阻塞超过 timeout_duration。” 是的 - 我已经看到了。但这仅仅意味着它可能会阻塞比你的超时时间长一点。因此,如果该操作需要 2 分钟,并且您指定 500 毫秒的超时,它将返回 much 早于 2 分钟。因此,如果您有很多线程,操作系统的调度程序可能不会立即切换回您,这可能会导致超时时间稍长。但它不会阻塞,直到异步操作终止。 关键是它可能 阻塞,即使指定等待0秒。它可能不会如您在回答中声称的那样立即返回。如果您只想知道未来是否已准备好,那么您希望避免阻塞和上下文/线程切换。 @K-ballo:测试未来是否准备好本质上是对共享状态的操作,因此它需要获取共享状态内的锁,这可能 阻止。也就是说,标准中的措辞并不意味着它除了显而易见的成本之外还有任何其他成本,并且您无法得到比wait_for 更好的任何东西。

以上是关于如何检查 std::async 任务是不是完成?的主要内容,如果未能解决你的问题,请参考以下文章

何时更喜欢 lambda 而不是带有 std::async 的打包任务? [复制]

主线程等待 std::async 完成[重复]

如何检查一个任务是不是完成并开始下一个?

std::async()

析构函数和异步任务

C# Task.Run() 与 C++ std::async()