C++std::async 异步操作 cppreference

async( std::launch policy, Function&& f, Args&&... args );
async( Function&& f, Args&&... args );
参数含义:
policy	-	位掩码值,每个单独位控制允许的执行方法
			- std::launch::async	启用异步求值
			- std::launch::deferred	启用惰性求值

f	-	要调用的可调用 (Callable) 对象

args...	-	传递给 f 的参数

#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <future>
#include <string>
#include <mutex>
 
std::mutex m;
struct X {
    void foo(int i, const std::string& str) {
    	//sleep(1); 
/*
The sum is 10000
world!
43
53
Hello 42				// 最后也没执行完,被析构的时候打印
*/
        std::lock_guard<std::mutex> lk(m);
        std::cout << str << ' ' << i << '\n';
    }
    void bar(const std::string& str) {
        std::lock_guard<std::mutex> lk(m);
        std::cout << str << '\n';
    }
    int operator()(int i) {
        std::lock_guard<std::mutex> lk(m);
        std::cout << i << '\n';
        return i + 10;
    }
};
 
template <typename RandomIt>
int parallel_sum(RandomIt beg, RandomIt end)
{
    auto len = end - beg;
    if (len < 1000)
        return std::accumulate(beg, end, 0);
 
    RandomIt mid = beg + len/2;
    auto handle = std::async(std::launch::async,
                             parallel_sum<RandomIt>, mid, end);		
    int sum = parallel_sum(beg, mid);
    return sum + handle.get();
}
 
int main()
{
    std::vector<int> v(10000, 1);
    std::cout << "The sum is " << parallel_sum(v.begin(), v.end()) << '\n';
 
    X x;
    // 以默认策略调用 x.foo(42, "Hello") :
    // 可能同时打印 "Hello 42" 或延迟执行
    auto a1 = std::async(&X::foo, &x, 42, "Hello");
    // 以 deferred 策略调用 x.bar("world!")
    // 调用 a2.get() 或 a2.wait() 时打印 "world!"
    auto a2 = std::async(std::launch::deferred, &X::bar, x, "world!");
    // 以 async 策略调用 X()(43) :
    // 同时打印 "43"
    auto a3 = std::async(std::launch::async, X(), 43);
    a2.wait();                     // 打印 "world!"   等价于 a2.get()
    std::cout << a3.get() << '\n'; // 打印 "53"
} // 若 a1 在此点未完成,则 a1 的析构函数在此打印 "Hello 42" (c++ 17及以上才行)

更换不同编译器打印结果可能为

The sum is 10000
world!
43
Hello 42
53
The sum is 10000
Hello 42
world!
43
53

async会返回一个future对象,当需要最终结果时,调用 std::future::get() 方法即可,该方法会阻塞线程直到期望值状态就绪为止。
future的析构函数和get()/wait()方法一样,也会阻塞

#include <iostream>
#include <future>
#include <chrono>

int main(){
    auto sleep = [](int s) { 
        std::this_thread::sleep_for(std::chrono::seconds(s)); 
    };
    
    {
        //std::async( std::launch::async, sleep, 5 ); // 临时对象被析构,阻塞 5s
        //std::async( std::launch::async, sleep, 5 ); // 临时对象被析构,阻塞 5s,共花费10s

        auto f1 = std::async( std::launch::async, sleep, 5 );		// 值传递给了临时对象,future可以马上析构,故两个同时析构只花费5s
        auto f2 = std::async( std::launch::async, sleep, 5 );
    }
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
std::asyncC++11标准库中的一个函数模板,用于创建一个异步任务,返回一个std::future对象,可以通过std::future对象获取异步任务的结果。 std::async的用法有以下几个步骤: 1. 包含头文件#include<future>。 2. 使用std::async创建异步任务,传入一个可调用对象(函数、函数指针、lambda表达式等)作为参数,标识异步任务的启动。 3. std::async会返回一个std::future对象,可以通过该对象获取异步任务的结果。 4. 可以通过std::future的成员函数get()获取异步任务的返回值,该调用会阻塞当前线程,直到异步任务完成并返回结果。也可以通过std::future的成员函数wait()等待异步任务的完成,再通过get()获取结果。 5. 可以通过std::future的成员函数valid()检查std::future对象是否可用,即异步任务是否完成并返回结果。 6. std::async还可以传入std::launch参数,显式指定异步任务的启动策略。例如,std::launch::async表示立即启动异步任务;std::launch::deferred表示延迟启动异步任务,直到调用std::future的成员函数get()或wait()时才启动。 7. 当std::async创建的异步任务完成后,std::future对象将被销毁,对std::future对象的后续操作将导致未定义的行为。 总而言之,std::async可以用于创建一个异步任务,并获得任务的返回值。它提供了一种简单的方式来进行并行编程,可以提高程序的性能和响应能力。但是需要注意的是,需要合理使用std::future对象以及与其相关的成员函数来处理异步任务的结果,避免潜在的阻塞或无效操作

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值