C++std::async 简单研究

它是 c++ 标准库提供的 API,用于异步(创建单独的线程)或同步(正常调用函数)执行任务(作为参数传递)。 这取决于启动策略。

参数

  • f 要调用的可调用 (Callable) 对象
  • args 传递给 f 的参数
  • policy 位掩码值,每个单独位控制允许的执行方法
解释
std::launch::async启用异步求值,运行新线程,以异步执行任务
std::launch::deferred启用惰性求值,在调用线程上执行任务(惰性求值)。在对 future 调用 get wait 的时候,才进行执行。如果什么都没有发生,那么执行函数就没有运行。
launch::async|launch::deferred这是自动的,该函数在特定点自动选择策略。 这取决于系统以及库实现,这通常针对系统中当前的并发可用性进行优化

注:不使用策略参数调用 async(f, 1, 2, 3) ,我们将会选择都是用的策略。 async 的实现可以自由的选择策略。这也就意味着,我们不能确定任务会执行在一个新的线程上,还是执行在当前线程上。

启动策略

启动策略是 std::async API 的一部分,它作为第一个参数传递。 共有三种启动策略 :

  • std::launch::async
  • std::launch::deferred
  • 默认策略(std::launch::async | std::launch::deferred)

std::launch::async

它将函数作为 单独的线程 启动,如果资源不可用,那么我们将得到异常(std::system_error 错误 std::resource::unavailable_try_again)。
例子:

//创建单独的线程
std::future<int>result1=std::async(std::launch::async,AddThread,3,3);

std::launch::deferred

它将函数作为 同步调用 当调用 futureget() wait() 时 启动。 如果有人使用延迟策略启动异步并且不调用 futureget() wait(),那么函数将永远不会启动 。
例子:

//Using std::launch::deferred policy, no separate thread.
auto result2 = std::async(std::launch::deferred, MulThread, 3, 3);

默认策略

它是上述两种策略的组合或留空(请查看下面的示例),它以异步方式(创建单独的线程)或同步方式(正常调用函数)启动函数,它取决于库,库将选择基于上述策略之一关于资源的可用性。
例子:

//Using Default Policy
//Both below function signature are same, we can use anyone.
std::async(std::launch::async|std::launch::deferred, AddThread, 6, 6);
or
std::async(AddThread, 6, 6);

综合示例

  • 示例1:
#include <future>
#include <iostream>
// 检查它是否是质数
// 参数是必须检查的数字
bool fnprime(int num) {
    std::cout << "处理开始。。。请等待。。。\n";
    int i = 1;

    while (1) {
        std::cout << "处理数值" << num << "  " << i << std::endl;
        i++;
        if (i > 100) {
            break;
        }
    }
    for (; i < num + 100; ++i) {
        // 如果 mod 为0,返回 false,否则返回0

        std::cout << "处理数值" << num << "  " << i << std::endl;
    }
    return true;
}
// main method
int main() {
    int num = 20;
    // 异步调用函数 fnprime ()检查数字是否为质数:
    std::future<bool> fobj = std::async(std::launch::async, [&]() -> bool {
        std::cout << "处理开始。。。请等待。。。\n";
        int i = 1;

        while (1) {
            std::cout << "处理数值" << num << "  " << i << std::endl;
            i++;
            if (i > 100) {
                break;
            }
        }
        for (; i < num + 100; ++i) {
            // 如果 mod 为0,返回 false,否则返回0

            std::cout << "处理数值" << num << "  " << i << std::endl;
        }
        return true;
    });
    // 打印该行以显示状态
    std::cout << "检查数字4是否为质数 . . \n";
    // 等待函数 fnPrime 返回
    // bool bobj = fobj.get();
    if (true)
        std::cout << "给出的数字是质数 . . .  ! \n";
    else
        std::cout << "给出的数字不是质数 . . .  ! \n\n";
    return 0;
}
g++ -std=c++11 -pthread ...
检查数字4是否为质数 . . 
给出的数字是质数 . . .  ! 
处理开始。。。请等待。。。
处理数值20  1
处理数值20  2
...
  • 示例2
// library for std::cout
#include <iostream>
// library for std::async and std::future
#include <future>
// library for std::string
#include <string>
std::string samplefunction(const std::string& st) {
    return "This is the output of " + st;
}
class SamplefunctionObject {
   public:
    std::string operator()(const std::string& st) const {
        return "This is the output of " + st;
    }
};
int main() {
    std::cout << std::endl;
    // future with the help of function
    auto ff = std::async(samplefunction, "sample function");
    // future with the help of function object
    SamplefunctionObject samplefunctionObject;
    auto ffo = std::async(samplefunctionObject, "sample function object");
    // future with the help of lambda function
    auto fl = std::async(
        [](const std::string& st) { return "This is the output of " + st; },
        " lambda function");
    std::cout << ff.get() << "\n" << ffo.get() << "\n" << fl.get() << std::endl;
    std::cout << std::endl;
}
This is the output of sample function
This is the output of sample function object
This is the output of  lambda function
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

-西门吹雪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值