zoukankan      html  css  js  c++  java
  • C++11 std::async 包装实体店::packaged_task

    更好的方式

    C++11中提供了操作多线程的高层次特性。

    • std::packaged_task 包装的是一个异步操作,相当与外包任务,好比我大阿里把电话客服外包给某某公司。
    • std::future 提供了一个访问异步操作结果的机制,这个是底层机制,在packaged_task和promise内部都有future来访问结果。

    说的比较干巴,还是上代码吧!

    #include <iostream>
    #include<vector>
    #include <future>
    using namespace std;
    
    long long jiechen(int n)
    {
        long long ret=1;
        for (int i=1;i<=n; i++)
            ret*=i;
        return ret;
    
    }
    
    int main()
    {
        vector<int> data={9,11,13,17,19};
        vector<future<long long>> fus;
        for (auto i:data)
        {
            packaged_task<long long() > pt(bind(jiechen,i));
            fus.push_back(std::move(pt.get_future()));
            std::thread(std::move(pt)).detach();
        }
        for(auto& i:fus)
        {
            i.wait();
            cout<<i.get()<<endl;
        }
        return 0;
    }
    

    比较简单,就没必要解释了。跟“古老”的方案比,还是有些不同的
    1. 不关心线程创建和结束
    2. 使用层面无共享数据,这个意味着写子线程函数时你不用小心翼翼担心线程安全问题。
    3. 抽象层次不同,古老方案本质上还是依靠负作用编程,新标准异步方式则某种程度上跳出了这个范畴。
    4,如有异常发生,新方案可以在外层处理异常。
    上面说了那么多,肯定还是有同学说,引入概念(计算机领域的概念真是多啊),变的难理解了,那有我直接操作线程干活爽。我又想要好处,又想好理解,有简单的方式吗,有简单的方式吗,有简单的方式吗?
    还真有:std::async

    最佳实践

    std::async的原型async(std::launch::async | std::launch::deferred, f, args...)

    std::launch::async:在调用async就开始创建线程。
    std::launch::deferred:延迟加载方式创建线程。调用async时不创建线程,直到调用了future的get或者wait时才创建线程。

    std::async是让大家透懒的,工作过程是这样的:async先将异步操作用packaged_task包装起来,然后将异步操作的结果放到std::promise中,这个过程就是创造未来的过程。外面再通过future.get/wait来获取这个未来的结果。完全可以理解为:
    async(func,args).get() 就是启动线程执行func并获取返回值。
    应用这个特性,上面的主线程代码变为:

    int main()
    {
        vector<int> data={9,11,13,17,19};
        vector<future<long long>> fus;
        for (auto i:data) fus.push_back(std::async(jiechen,i));
        for(auto& i:fus)
        {
            i.wait();
            cout<<i.get()<<endl;
        }
    
        return 0;
    }
    

    std:async 不是弄出来捣乱的玩意,真的是异步编程利器,至少,在跨平台时不用改代码不是。在项目中,大家应该尽力避免直接调用低层次接口,直接调用async创建新线程。
    以上是一家之言,难免偏颇,欢迎探讨。

  • 相关阅读:
    数据机构与算法学习(四)- 链表
    DFS深度优先
    LeetCode.98验证二叉树
    输入一个有符号整数,输出该整数的反转值。
    如何交换两个对象
    泛型简介,泛型类及使用
    一个普通的逻辑问题
    for循环
    第一次比赛唯一ACCEPT的题目笑哭
    输入100以内具有10个以上因子的整数 并输出它的因子
  • 原文地址:https://www.cnblogs.com/diegodu/p/6737973.html
Copyright © 2011-2022 走看看