• 并发编程 —— 使用期望值等待一次性事件


    C++ 标准库中,有两种期望值,使用两种类型模板实现,声明在 <future> 头文件中 :   
    唯一期望值 (unique futures)( std::future<> )
    共享期望值 (shared    futures)( std::shared_future<> )。

    对于简单的一次性事件,比如,在后台运行计算结果, 但是std::thread 并不提供直接接收返回值的机制。
    使用std::async和std::future来实现:

    #include <unistd.h>
    
    #include <future>
    #include <iostream>
    
    int calculator(int a, int b) { return a + b; }
    
    int main() {
        //使用 std::async 启动一个异步任务,返回一个 std::future 对象
        std::future<int> the_answer = std::async(calculator, 1, 1);
        sleep(2);  // do something
        //调用对象的get(),阻塞返回计算结果
        std::cout << "the answer is " << the_answer.get() << std::endl;
        return 0;
    }

    std::async允许添加额外的函数参数,具体实例如下:

    struct X{
        void foo(int, std::string const&);
        std::string bar(std::string const&);
    };
    
    X x;
    auto f1 = std::async(&X::foo, &x,42, "Hello");  //调用p->foo(42,"hello"),p是指向x的指针
    auto f2 = std::async(&X::bar, x, "goodbye");    //调用tmpx.bar("goodbye"),tmpx是x的拷贝副本
    
    struct Y{
        double operator()(double);
    };
    Y y;
    auto f3 = std::async(Y(), 3.141);          //调用tmpy(3.141),tmpy通过Y的移动构造函数得到
    //使用std::ref可以在模板传参的时候传入引用,否则无法传递
    auto f4 = std::async(std::ref(y), 2.718);  //调用y(2.718)
    
    X baz(&x);
    std::async(baz, std::ref(x));   //调用baz(x)

    在默认情况下,期望值是否等待取决于std::async 是否启动一个线程,或是否有任务正在进行同步。
    还可以在函数调用之前向 std::async 传递 std::lanuchstd::launch::defered,表明函数调用被延迟到wait()或get()函数调用时才执行,std::launch::async 表明函数必须在其所在的独立线程上执行。如下:

    auto f6 = std::async(std::launch::async, Y(), 1, 2);    //在新线程上执行
    auto f7 = std::async(std::launch::deferred, std::ref(x));  //在wait()或get()调用时执行
    
    auto f8 = std::async(4. std ::launch ::deferred | std ::launch ::async, baz,
                          std ::ref(x));  //实现选择执行方式
    auto f9 = std::async(baz, std ::ref(x));
    f7.wait();  //调用延迟函数

    在上面的实例中,我们使用std::async让算法分割在各个任务中,从而实现并发。
    当然,我们还可以通过其他方法关连 std::future 与任务实例,如,将任务包装入 std::package_task<>实例中
    或使用std::promise<>l类型模板显示设置值。

  • 相关阅读:
    加分二叉树
    逃离牧场
    [Apio2012]dispatching
    靶形数独
    POJ 1459-Power Network(网络流-最大流-ISAP)C++
    题解 最优的挤奶方案(Optimal Milking)
    [HNOI2007]紧急疏散EVACUATE (湖南2007年省选)
    【LCA求最近公共祖先+vector构图】Distance Queries
    BZOJ1143: [CTSC2008]祭祀river
    BZOJ2140: 稳定婚姻
  • 原文地址:https://www.cnblogs.com/y4247464/p/15615330.html
Copyright © 2020-2023  润新知