1. 基本使用
#if 1
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<thread>
#include<chrono>
#include<future>
void task(std::promise<int>& prom, int number)
{
std::this_thread::sleep_for(std::chrono::seconds(2));
prom.set_value(100 + number);
}
void test()
{
// 用于子线程设置返回值,模板参数为返回给主线程值的类型
std::promise<int> prom;
// 用于主线程获得返回值
std::future<int> fut = prom.get_future();
// std::thread 要求传递的参数能够被拷贝或者移动,而 std::promise 不支持拷贝,但支持移动
// 所以,此处可以使用 ref 或者 move 包装 promise 进行传递
// 使用 ref:task 参数设置为左值引用
// 使用 move:task 参数设置为右值引用
std::thread t(task, std::ref(prom), 200);
//std::thread t(task, std::move(prom), 200);
t.join();
// 建议:使用 ref,而不是 move,原因如下:
// 使用 ref 传递更加高效,而 move 会导致对象在 thread 内部的移动操作
// 通过 future 阻塞获得线程任务结果
std::cout << "result:" << fut.get() << std::endl;
}
int main()
{
test();
return EXIT_SUCCESS;
}
#endif
2. std::promise
#if 1
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<thread>
#include<chrono>
#include<future>
#if 1
void my_div(std::promise<double>& prom, double num1, double num2)
{
std::this_thread::sleep_for(std::chrono::seconds(2));
if (0 == num2)
{
auto my_exception = std::make_exception_ptr(std::runtime_error("除零异常!"));
prom.set_exception(my_exception);
}
else
{
// 将结果保存到 future 对象中,并通知 future 对象
prom.set_value(num1 / num2);
// 注意:promise 对象不允许重复设置 value,否则会抛出异常
// prom.set_value(num1 / num2);
}
}
#else
void my_div(std::promise<double>& prom, double num1, double num2)
{
std::this_thread::sleep_for(std::chrono::seconds(2));
try
{
if (0 == num2)
{
throw std::runtime_error("除零异常!");
}
prom.set_value(num1 / num2);
}
catch (...)
{
prom.set_exception(std::current_exception());
}
}
#endif
void test()
{
std::promise<double> prom;
std::future<double> fut = prom.get_future();
std::thread t(my_div, std::ref(prom), 100, 0);
t.detach();
try
{
std::cout << "result:" << fut.get() << std::endl;
}
catch (std::exception& ex)
{
std::cout << ex.what() << std::endl;
}
}
int main()
{
test();
return EXIT_SUCCESS;
}
#endif
3. std::future
#if 1
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<thread>
#include<chrono>
#include<future>
void task(std::promise<int>& prom, int number)
{
std::this_thread::sleep_for(std::chrono::seconds(2));
prom.set_value(100 + number);
}
// 1. future 其他函数
void test01()
{
std::promise<int> prom;
std::future<int> fut = prom.get_future();
std::thread t(task, std::ref(prom), 200);
// 从结果的角度:等待任务结束
// fut.wait();
// 阻塞等待状态 ready,或者达到等待时间,返回状态
std::future_status status = fut.wait_for(std::chrono::seconds(3));
// std::future_status status = fut.wait_until(std::chrono::steady_clock::now() + std::chrono::seconds(2));
if (status == std::future_status::timeout)
{
std::cout << "任务正在执行..." << std::endl;
}
if (status == std::future_status::ready)
{
std::cout << "任务执行完毕,任务结果是:" << fut.get() << std::endl;
}
// 从线程的角度:等待任务结束
t.join();
}
// 2. shared future
void test02()
{
std::promise<int> prom;
// std::future<int> fut = prom.get_future();
// 使用 shared_future 代替 future,可以实现多次获得值
std::shared_future<int> fut = prom.get_future();
std::thread t(task, std::ref(prom), 200);
std::cout << fut.get() << std::endl;
std::cout << fut.get() << std::endl;
t.join();
}
int main()
{
test01();
return EXIT_SUCCESS;
}
#endif