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版权协议,转载请附上原文出处链接和本声明。