C++多线程中的future(期望)

版权声明:所有的博客都是博主的个人笔记。。。。。 https://blog.csdn.net/qq_35976351/article/details/84186042

Providers

std::promise

std::future配合使用,给std::future传递期望值,下面是最简单的一个用法:

#include <iostream>
#include <functional>
#include <thread>
#include <future>

// 一定要注意是传递引用
void print_int(std::future<int>& fut) {
    auto x = fut.get();  // 如果future中没有值,那么在这里一直等待
    std::cout << "value: " << x << std::endl;
}

int main() {
    std::promise<int> prom;
    std::future<int> fut = prom.get_future(); // 获取承诺的future
    std::thread th1(print_int, std::ref(fut));
    std::cout << "Please input a value:";
    int n;
    std::cin >> n;
    prom.set_value(n);  // 把数据传递给承诺的future中
    th1.join();
    return 0;
}

packaged_task

这是一个更高级的封装,封装的元素是可调用对象,对比上面的promise,那个是仅仅封装数值的。

构造方式:

template <class T> packaged_task;     // undefined
template <class Ret, class... Args> class packaged_task<Ret(Args...)>;

实例说明:

#include <iostream>
#include <future>
#include <chrono>
#include <thread>

int countdown(int from, int to) {
    for(int i = from; i != to; --i) {
        std::cout << i << std::endl;
        // 线程休眠1秒
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
    std::cout << "Lift off\n";
    return from - to;
}

int main() {
    std::packaged_task<int(int, int)>tsk(countdown);
    std::future<int>ret = tsk.get_future();
    // 构造线程开始执行任务,注意是移动构造
    std::thread th(std::move(tsk), 10, 0);
    // 没有返回结果时,当前线程就一直阻塞
    int value = ret.get();
    std::cout << "The countdown lasted for " << value << " seconds\n";
    th.join();
    return 0;
}

Futures

两者只支持移动赋值,无法进行复制操作。

std::future

期望,用于同步数据或者是等待其他线程的异步通信结果。

template <class T>  future;
template <class R&> future<R&>;     // specialization : T is a reference type (R&)
template <>         future<void>;   // specialization : T is void

成员函数:

T get();
R& future<R&>::get();       // when T is a reference type (R&)
void future<void>::get();   // when T is void

具体实例参照上面。在不调用wait类函数的情况下,如果还没计算完成,就一直等待到计算完成。

void wait() const;

等待计算结果完毕,调用完成该函数后,再次调用get()函数,仅仅是返回一个状态,例如:

// future::wait
#include <iostream>       // std::cout
#include <future>         // std::async, std::future
#include <chrono>         // std::chrono::milliseconds

// a non-optimized way of checking for prime numbers:
bool is_prime (int x) {
    for (int i = 2; i < x; ++i)
        if (x % i == 0)
            return false;
    return true;
}

int main () {
    // call function asynchronously:
    std::future<bool> fut = std::async (is_prime, 194232491);

    std::cout << "checking...\n";
    fut.wait();

    std::cout << "\n194232491 ";
    if (fut.get())      // guaranteed to be ready (and not block) after wait returns
        std::cout << "is prime.\n";
    else
        std::cout << "is not prime.\n";
    return 0;
}
template <class Rep, class Period>
  future_status wait_for (const chrono::duration<Rep,Period>& rel_time) const;

等待计算完毕或者到达指定时间,之后程序继续执行,rel_time是指的时间间隔。

template <class Clock, class Duration>
  future_status wait_until (const chrono::time_point<Clock,Duration>& abs_time) const;

类似于wait_for,不过abs_time是指的绝对时间点

扫描二维码关注公众号,回复: 4119295 查看本文章

std::shared_future

包含了std::future的所有功能,但是可以进行复制操作。

Functions

async

一个异步调用,不等待计算结果,立刻返回一个std::future类型。计算的结果由返回的std::futureget()成员获取。

构造函数:

template <class Fn, class... Args>
future<typename result_of<Fn(Args...)>::type>
  async (Fn&& fn, Args&&... args);
    
template <class Fn, class... Args>
future<typename result_of<Fn(Args...)>::type>
  async (launch policy, Fn&& fn, Args&&... args);

一般只使用第一个,第二个的策略具体查询手册即可。

代码实例:

#include <iostream>
#include <future>

bool is_prime(int x) {
    std::cout << "Calculating. Please, wait...\n";
    for(int i = 2; i < x; ++i) {
        if(x % i == 0)
            return false;
    }
    return true;
}

int main() {
    std::future<bool>fut = std::async(is_prime, 313222313);
    std::cout << "Checking whether 313222313 is prime.\n";
    bool ret = fut.get(); // 获取结果,在计算出结果之前,这个会一直阻塞
    if(ret) {
        std::cout << "It is prime !\n";
    } else {
        std::cout << "It is not prime !\n";
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_35976351/article/details/84186042