std::async、std::future、std::packaged_task、std::promise

一、std::async函数模板、std::future类模板

#include <future>
std::async 是个函数模板,返回一个 std::future 对象(类模板)
作用是启动一个异步任务,就是自动创建一个线程并开始执行对应的线程入口函数
可以通过future 的get() 函数来获得线程的返回结果

示例

class MyClass
{
public:
    int MyThread(int param);   // 假定一个线程函数是有返回值的
};

int main()
{
    MyClass ele;
    // 注意std::launch::deferred参数的位置
    std::future<int> result = std::async(std::launch::deferred, &MyClass::MyThread, &ele, 5);
    // 创建一个线程,并开始执行,线程入口是MyThread程,此处程序不会阻塞
    int getResult = result.get();   // 获得线程返回的结果值,
    // 只能调用一次,否则会编译报错
    // 此时如果MyThread线程没有执行完,程序会阻塞在这,直到拿到这个线程的返回值
    result.wait();   // 只是等待result 绑定的线程返回,不会获得线程的返回值

    // 也可以给async() 函数传递一个参数,参数类型为std::lunnch (枚举类型)
    // (1)std::launch::deferred :表示线程函数的入口函数,延迟到future 的wait()或者get()函数调用时才执行
    // 如果不调用future 的wait()或者get()函数,整个的线程都不会创建
    // 没有新线程创建,是在主线程中调用线程入口函数
    // (2)std::launch::async :表示在调用async函数的时候就开始创建新线程,立即执行新线程
// (3)不带参数表示可能创建新线程,也可能不创建新线程,根据系统的资源情况来定
cout << "主线程" << endl; system("pause"); return 0; }

二、std::packaged_task

std::packaged_task : 类模板,模板参数是可调用对象
打包任务,把各种可调用对象包装起来,方便将来作为线程函数入口来调用

int MyThread2(int param) { return 5; } // 假定一个线程函数是有返回值的

//std::packaged_task : 类模板,模板参数是可调用对象
//打包任务,把各种可调用对象包装起来,方便将来作为线程函数入口来调用
std::packaged_task<int(int)> mypt(MyThread2);
std::thread t1(std::ref(mypt), 1);    // 线程开始执行
std::future<int> result2 = mypt.get_future();   // 将result 和mypt 绑定到一起
t1.join();

三、std::promise 类模板

void MyPromiseThread(std::promise<int> &promise, int param)
{
    // 其中对参数param 进行一系列的操作
    int res = param;
    promise.set_value(res); // 将最终的值保存到promise 中
    return;
}

void GetValueThread(std::future<int>& future)
{
    auto res = future.get();
    // 对res的操作
}

int main()
{
    std::promise<int> myPromise;   // 其中保存值得类型为 int
    std::thread proThread(MyPromiseThread, std::ref(myPromise), 10);
    proThread.join();
    std::future<int> fuRes = myPromise.get_future();   // myPromise 和 future 绑定
    int res = fuRes.get();       // 获取myPromise 的结果
    // 说明future 可以和多种类型绑定,具体需要查资料
    // 总结:通过promise 绑定一个值,在将来某个时刻我们通过future 绑定这个promise 得到这个绑定值

    std::thread getValueThread(GetValueThread, std::ref(fuRes));   
    // 将MyPromiseThread 线程中的值传递到GetValueThread 线程中
    getValueThread.join();
    return 0;
}

 

posted @ 2020-06-26 18:40  min_zhi  阅读(214)  评论(0编辑  收藏  举报