c++11 之 async

promise和promise基本原理:

线程1初始化一个promise对象和一个future对象然后把promise传递给线程2

线程2于是对线程1有了一个promise

future相当于一个接受一个promise,用来获取未来线程2传递的值


线程2获取到promise后,需要对这个promise传递有关的数据,之后线程1的future就可以获取数据了。


线程1阻塞等待线程2的数据到达

 

 

使用方法:https://blog.csdn.net/hyl999/article/details/106260324

1 promise和future成对出现并绑定:

    //声明一个std::promise对象promise1,其保存的值类型为int
    std::promise<int> promise1;
    //声明一个std::future对象future1,并通过std::promise的get_future()函数与promise1绑定
    std::future<int> future1 = promise1.get_future();

2 创建线程:

    //创建一个线程t1,将函数Thread_Fun1及对象promise1放在线程里面执行
    std::thread t1(Thread_Fun1, std::ref(promise1));
    //创建一个线程t2,将函数Thread_Fun2及对象future1放在线程里面执行
    std::thread t2(Thread_Fun2, std::ref(future1));

3 线程中对promise对象调用set_value,对future对象调用get

 

让promise和future的参数是function:

#include <iostream>
#include <future>
#include <chrono>
#include <functional>
 
//声明一个可调对象T
using T = std::function<int(int)>;        //等同于typedef std::function<int(int)> T;
 
int Test_Fun(int iVal)
{
    std::cout << "Value is:" << iVal << std::endl;
    return iVal + 232;
}
 
void Thread_Fun1(std::promise<T> &p)
{
    //为了突出效果,可以使线程休眠5s
    std::this_thread::sleep_for(std::chrono::seconds(5));
 
    std::cout << "传入函数Test_Fun" << std::endl;
 
    //传入函数Test_Fun
    p.set_value(std::bind(&Test_Fun, std::placeholders::_1));
}
 
void Thread_Fun2(std::future<T> &f)
{
    //阻塞函数,直到收到相关联的std::promise对象传入的数据
    auto fun = f.get(); 
 
    int iVal = fun(1);
 
    std::cout << "收到函数并运行,结果:" << iVal << std::endl;       //iVal = 233
}
 
int main()
{
    //声明一个std::promise对象pr1,其保存的值类型为int
    std::promise<T> pr1;
    //声明一个std::future对象fu1,并通过std::promise的get_future()函数与pr1绑定
    std::future<T> fu1 = pr1.get_future();
 
    //创建一个线程t1,将函数Thread_Fun1及对象pr1放在线程里面执行
    std::thread t1(Thread_Fun1, std::ref(pr1));
    //创建一个线程t2,将函数Thread_Fun2及对象fu1放在线程里面执行
    std::thread t2(Thread_Fun2, std::ref(fu1));
 
    //阻塞至线程结束
    t1.join();
    t2.join();
 
    return 1;

传入可变元参数:


#include <iostream>
#include <future>
#include <chrono>
#include <functional>
 
//声明一个可调对象F
using F = std::function<int(int, int, int&)>;        //等同于typedef std::function<int(int, int, int&)> F;
 
//函数可以改成任意参数,任意返回类型
int Test_Fun(int a, int b, int &c)
{
    //a = 1, b = 2
    c = a + b + 230;
    return c;
}
 
void Thread_Fun1(std::promise<F> &p)
{
    //为了突出效果,可以使线程休眠5s
    std::this_thread::sleep_for(std::chrono::seconds(5));
 
    std::cout << "传入函数Test_Fun" << std::endl;
 
    //传入函数Test_Fun
    p.set_value(std::bind(&Test_Fun, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
}
 
template<typename T, typename ...Args>
void Thread_Fun2(std::future<T> &f, Args&& ...args)
{
    //阻塞函数,直到收到相关联的std::promise对象传入的数据
    auto fun = f.get();        //fun等同于Test_Fun
 
    auto fResult = fun(std::forward<Args>(args)...);
 
    std::cout << "收到函数并运行,结果:" << fResult << std::endl;
}
 
int main()
{
    //声明一个std::promise对象pr1,其保存的值类型为int
    std::promise<F> pr1;
    //声明一个std::future对象fu1,并通过std::promise的get_future()函数与pr1绑定
    std::future<F> fu1 = pr1.get_future();
 
    //声明一个变量
    int iVal = 0;
 
    //创建一个线程t1,将函数Thread_Fun1及对象pr1放在线程里面执行
    std::thread t1(Thread_Fun1, std::ref(pr1));
    //创建一个线程t2,将函数Thread_Fun2及对象fu1放在线程里面执行
    std::thread t2(Thread_Fun2<F, int, int, int&>, std::ref(fu1), 1, 2, std::ref(iVal));
 
    //阻塞至线程结束
    t1.join();
    t2.join();
 
    //此时iVal的值变成233
 
    return 1;
}

async的例子:std::async的操作,其实相当于封装了std::promise、std::packaged_task加上std::thread。

// future example
#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,444444443);

  // do something while waiting for function to set future:
  std::cout << "checking, please wait";
  std::chrono::milliseconds span (100);
  while (fut.wait_for(span)==std::future_status::timeout)
    std::cout << '.' << std::flush;

  bool x = fut.get();     // retrieve return value

  std::cout << "\n444444443 " << (x?"is":"is not") << " prime.\n";

  return 0;
}

https://www.cnblogs.com/moodlxs/p/10111601.html

 

 

std::async使我们不用关注线程创建内部细节,就能方便的获取异步执行状态和结果,还可以指定线程创建策略,可以用std::async替代线程的创建

async(std::launch::async | std::launch::deferred, f, args...),第一个参数是线程的创建策略,有两种策略,默认的策略是立即创建线程:

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

第二个参数是线程函数,第三个参数是线程函数的参数。

async的其它例子:

std::future<int> f1 = std::async(std::launch::async, [](){ 
        return 8;  
    }); 

cout<<f1.get()<<endl; //output: 8

std::future<int> f2 = std::async(std::launch::async, [](){ 
        cout<<8<<endl;
    }); 

f2.wait(); //output: 8

std::future<int> future = std::async(std::launch::async, [](){ 
        std::this_thread::sleep_for(std::chrono::seconds(3));
        return 8;  
    }); 
 
    std::cout << "waiting...\n";
    std::future_status status;
    do {
        status = future.wait_for(std::chrono::seconds(1));
        if (status == std::future_status::deferred) {
            std::cout << "deferred\n";
        } else if (status == std::future_status::timeout) {
            std::cout << "timeout\n";
        } else if (status == std::future_status::ready) {
            std::cout << "ready!\n";
        }
    } while (status != std::future_status::ready); 
 
    std::cout << "result is " << future.get() << '\n';


可能的结果:
waiting...
timeout
timeout
ready!
result is 8

 


版权声明:本文为icebergliu1234原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。