白话C++》第12章并发,Page525 异步调用策略

异步调用策略:

C++允许我们强行指定异步活动的启动策略(launch policy)。

异步调用策略是一个枚举值,采用了C++11下,带class的枚举定义:

enum class launch:{async/*异步*/, deferred/*延期*/};

标准暂时仅要求提供两种策略。

launch::async表示本次异步操作强制要求立即开工,通常就是后台必须立即启动新线程以便执行任务;

launch::defered则强制要求本次异步操作暂时不开始,直到遇上调用future对象的get(),这种效果相当于延缓了任务的执行(原来代码也有拖延症)。

对应的async()函数版本,是在参数列表最前面新加一个入参:

future <T> async(std::launch policy, Function&& f, Args&&... args);

【危险】:发起异步操作的第三种策略

调用无policy入参版本的async()函数,使用的是什么策略?肯定不是launch::deferred,但也不一定是launch::async,而是交由程序临时决定。可能立即启动异步操作,也可能拖延一阵再开始,当然也有可能拖到get()函数被调用后才启动。后面我们称它为“临时决定”策略。

请牢记一点,仅在你的确不在意异步操作可能延迟的情况下,才使用无需指定策略的异步调用函数

测试带调用策略版的async函数。首先定义一个简单的任务函数,用于在屏幕上输出100次指定短字符串:

void output(char const* s)
{
    for(int i = 0; i < 100; ++i)
    {
        cout << s;
        //确保每次输出不缓存,直接输出到屏幕
        cout.flush();
    }
}
void test4()
{
    //小张,你到门口持续叫“呜”
    std::future <void> future_1
            //std::launch::async是异步策略
        = std::async(std::launch::async, output, "呜");

    //小李,你到门口持续叫“哦”
    std::future <void> future_2
            //std::launch::deferred是延期策略
        = std::async(std::launch::deferred, output, "哦");

    //领导我负责就地持续叫“哇”
    output("哇");

    future_1.get();
    future_2.get();
}

运行效果:很明显,小李在开始时偷懒,它是直到future_2.get()时才开始叫。

【课堂作业】:异步代用lambda

请将以上那个热闹的例子做如下修改:在调用async时,直接传入lambda表达式。

这个例子还有一个地方需要稍加注意:output函数有入参,无返回值,因此在调用async是,需要填写额外的入参,也就是各种叫声,而返回的future需以void作为模板入参,这会在背后产生一个特殊的future,它的get()方法同样返回void

另外,我们可能会不想重复写长长的future<T>类型,因此会用上auto,类似:

auto f = async(launch::async, output, "哼");

解答:

一:

二:

三:

  • 11
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值