zoukankan      html  css  js  c++  java
  • 并发编程 —— 使用期望值等待一次性事件

    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类型模板显示设置值。

  • 相关阅读:
    iOS-Core Text 入门
    Mac浏览器全屏设置
    Quartz 2D - 图形上下文(Graphics Contexts)
    Quartz 2D 概述
    Quartz 2D官方文档翻译(持续更新中)
    那些年,我们常掉进去的坑
    CGAffineTransformMake(a,b,c,d,tx,ty) 矩阵运算的原理 (转载)
    科大讯飞
    Object-C语言类的扩展
    科大讯飞语音识别
  • 原文地址:https://www.cnblogs.com/y4247464/p/15615330.html
Copyright © 2011-2022 走看看