You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让C++异步调用按完成顺序返回结果?

按异步任务完成顺序获取结果的C++实现

你的原代码通过std::async启动异步任务,但遍历std::future时按调用顺序调用get(),因此输出顺序固定为任务启动顺序。要实现按任务完成顺序输出结果,std::experimental::when_any是可行方案——尽管它属于实验特性,但主流编译器(GCC、Clang、MSVC)在开启对应选项后均支持使用。

修改后的示例代码

#include <iostream>       
#include <future>         
#include <chrono>
#include <thread>
#include <utility>
#include <string> 
#include <vector>
#include <experimental/future>  // 引入when_any头文件

std::pair<int, std::string> check_even(int num){
    std::this_thread::sleep_for(std::chrono::milliseconds((10 - num) * 100));
    if(num % 2 == 0) return {num, "even"};
    return {num, "odd"};
}

int main(){
    std::vector<std::future<std::pair<int, std::string>>> futures;
    for(int i = 0; i < 10; i++){
        futures.push_back(std::async(std::launch::async, check_even, i));
        // 显式指定std::launch::async确保任务异步执行(默认策略可能选择同步)
    }

    while(!futures.empty()){
        // 调用when_any获取第一个完成的任务
        auto result = std::experimental::when_any(futures.begin(), futures.end());
        
        // 获取已完成任务的索引
        size_t completed_idx = result.index;
        // 获取任务结果
        auto rs = futures[completed_idx].get();
        std::cout << rs.first << " is " << rs.second << '\n';
        
        // 移除已处理的future,继续等待剩余任务
        futures.erase(futures.begin() + completed_idx);
    }

    return 0;
}

关键说明

  1. 头文件依赖:需要引入<experimental/future>来使用std::experimental::when_any。
  2. 显式异步策略:原代码中std::async默认策略可能选择同步执行,因此显式指定std::launch::async确保任务在独立线程中运行。
  3. when_any的作用:when_any接受一个std::future的范围,返回一个包含以下信息的结构体:
    • index:第一个完成任务在原容器中的索引
    • futures:原容器的副本(其中已完成的future处于ready状态)
  4. 编译选项:使用GCC编译时需添加参数-std=c++17 -lstdc++experimental,Clang类似,MSVC可直接启用C++17及以上标准编译。

预期输出

由于任务的休眠时间随num增大而缩短,任务完成顺序为9→8→7→…→0,输出如下:

9 is odd
8 is even
7 is odd
6 is even
5 is odd
4 is even
3 is odd
2 is even
1 is odd
0 is even

内容的提问来源于stack exchange,提问作者Caio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 16:52:42