文章目录
- 1.std::future
- 1.1 get()
- 1.2 valid()
- 1.3 share()
- 1.4 wait_for()
- 1.4.1 std::future_status::timeout
- 1.4.2 std::future_status::ready
- 1.4.3 std::future_status::deferred
- 2.std::shared_future
- 3.参考资料
1.std::future
std::future 是个类模板,其源码如下所示。std::future 可以用来获取异步任务的结果,通常与 std::async、std::packaged_task、std::promise 等搭配使用。
1.1 get()
在下面代码中,std::async() 用来启动一个异步任务,即自动创建一个线程并开始执行对应的线程入口函数,返回一个 std::future 对象,这个 std::future 对象里边就含有线程返回的结果(即线程入口函数所返回的结果),我们可以通过调用 std::future 对象的成员函数 get() 来获取结果。
需要注意的是,std::future 的 get() 只能调用一次,不能调用多次,因为其内部是移动语义。
#include <iostream>
#include <future>
using namespace std;
int mythread(int val) // 线程入口函数
{
cout << "mythread start, " << "mythread id = " << std::this_thread::get_id() << endl;
std::this_thread::sleep_for(std::chrono::milliseconds(5000)); // 休息5秒
cout << "mythread end, " << "mythread id = " << std::this_thread::get_id() << endl;
return val;
}
int main()
{
cout << "main start, " << "main id = " << std::this_thread::get_id() << endl;
std::future<int> result = std::async(std::launch::async, mythread, 180); // 创建一个线程并开始执行,流程并不会卡在这里
cout << "main continue..." << endl;
cout << result.get() << endl; // 卡在这里等待mythread线程执行完毕,拿到结果
cout << "main end, " << "main id = " << std::this_thread::get_id() << endl;
return 0;
}
1.2 valid()
valid() 检查当前的 std::future 对象是否有效,即是否与某个共享状态相关联。一个有效的 std::future 对象只能通过 std::async()、std::packaged_task::get_future() 或 std::promise::get_future() 来初始化。
需要注意的是,由 std::future 默认构造函数创建的 std::future 对象是无效的。
1.3 share()
share() 返回一个 std::shared_future 对象。如果某个 std::future 对象调用了 share() 函数,那么该 std::future 对象就不和任何共享状态相关联了,因为其内部是移动语义。
1.4 wait_for()
wait_for() 的返回值类型如下:
1.4.1 std::future_status::timeout
#include <iostream>
#include <future>
using namespace std;
int mythread(int val) // 线程入口函数
{
cout << "mythread start, " << "mythread id = " << std::this_thread::get_id() << endl;
std::this_thread::sleep_for(std::chrono::milliseconds(5000)); // 休息5秒
cout << "mythread end, " << "mythread id = " << std::this_thread::get_id() << endl;
return val;
}
int main()
{
cout << "main start, " << "main id = " << std::this_thread::get_id() << endl;
std::future<int> result = std::async(std::launch::async, mythread, 180); // 创建一个线程并开始执行,流程并不会卡在这里
cout << "main continue..." << endl;
std::future_status status = result.wait_for(std::chrono::seconds(1));
// 在主线程中等待1秒,1秒后mythread线程还没有执行完毕,即mythread线程timeout
if (status == std::future_status::timeout)
{
cout << "timeout" << endl;
}
cout << result.get() << endl; // 卡在这里等待mythread线程执行完毕,拿到结果
cout << "main end, " << "main id = " << std::this_thread::get_id() << endl;
return 0;
}
1.4.2 std::future_status::ready
#include <iostream>
#include <future>
using namespace std;
int mythread(int val) // 线程入口函数
{
cout << "mythread start, " << "mythread id = " << std::this_thread::get_id() << endl;
std::this_thread::sleep_for(std::chrono::milliseconds(5000)); // 休息5秒
cout << "mythread end, " << "mythread id = " << std::this_thread::get_id() << endl;
return val;
}
int main()
{
cout << "main start, " << "main id = " << std::this_thread::get_id() << endl;
std::future<int> result = std::async(std::launch::async, mythread, 180); // 创建一个线程并开始执行,流程并不会卡在这里
cout << "main continue..." << endl;
std::future_status status = result.wait_for(std::chrono::seconds(8));
// 在主线程中等待8秒,8秒后mythread线程已经执行完毕,即mythread线程ready
if (status == std::future_status::ready)
{
cout << "ready" << endl;
}
cout << result.get() << endl; // 拿到结果
cout << "main end, " << "main id = " << std::this_thread::get_id() << endl;
return 0;
}
1.4.3 std::future_status::deferred
#include <iostream>
#include <future>
using namespace std;
int mythread(int val) // 线程入口函数
{
cout << "mythread start, " << "mythread id = " << std::this_thread::get_id() << endl;
std::this_thread::sleep_for(std::chrono::milliseconds(5000)); // 休息5秒
cout << "mythread end, " << "mythread id = " << std::this_thread::get_id() << endl;
return val;
}
int main()
{
cout << "main start, " << "main id = " << std::this_thread::get_id() << endl;
std::future<int> result = std::async(std::launch::deferred, mythread, 180);
cout << "main continue..." << endl;
// 如果async()的启动策略被设置为std::launch::deferred,那么主线程并不会等待8秒,wait_for()函数会直接返回,下面判断成立
std::future_status status = result.wait_for(std::chrono::seconds(8));
if (status == std::future_status::deferred)
{
cout << "deferred" << endl;
}
cout << result.get() << endl; // 在主线程中去执行mythread()函数,拿到结果
cout << "main end, " << "main id = " << std::this_thread::get_id() << endl;
return 0;
}
2.std::shared_future
std::shared_future 也是个类模板,与 std::future 的作用相同。
不同之处在于,std::shared_future 可复制,并且多个 std::shared_future 对象可以关联同一个共享状态,其源码如下所示。
std::shared_future 的 get() 可以调用多次。
#include <iostream>
#include <future>
using namespace std;
int mythread(int val) // 线程入口函数
{
cout << "mythread start, " << "mythread id = " << std::this_thread::get_id() << endl;
std::this_thread::sleep_for(std::chrono::milliseconds(5000)); // 休息5秒
cout << "mythread end, " << "mythread id = " << std::this_thread::get_id() << endl;
return val;
}
int main()
{
cout << "main start, " << "main id = " << std::this_thread::get_id() << endl;
std::shared_future<int> ret = std::async(std::launch::async, mythread, 180); // 创建一个线程并开始执行,流程并不会卡在这里
cout << "main continue..." << endl;
cout << ret.get() << endl; // 卡在这里等待mythread线程执行完毕,拿到结果
cout << ret.get() << endl; // 拿到结果
cout << ret.get() << endl; // 拿到结果
cout << "main end, " << "main id = " << std::this_thread::get_id() << endl;
return 0;
}
#include <iostream>
#include <future>
using namespace std;
int mythread(int val) // 线程入口函数
{
cout << "mythread start, " << "mythread id = " << std::this_thread::get_id() << endl;
std::this_thread::sleep_for(std::chrono::milliseconds(5000)); // 休息5秒
cout << "mythread end, " << "mythread id = " << std::this_thread::get_id() << endl;
return val;
}
int main()
{
cout << "main start, " << "main id = " << std::this_thread::get_id() << endl;
std::future<int> ret; // 由默认构造函数创建的std::future对象是无效状态
cout << ret.valid() << endl; // 0
ret = std::async(std::launch::async, mythread, 180); // 创建一个线程并开始执行,流程并不会卡在这里
cout << ret.valid() << endl; // 1
cout << "main continue..." << endl;
std::shared_future<int> sret(ret.share()); // 移动构造sret,ret变为空
cout << sret.get() << endl; // 卡在这里等待mythread线程执行完毕,拿到结果
cout << sret.get() << endl; // 拿到结果
cout << sret.get() << endl; // 拿到结果
cout << "main end, " << "main id = " << std::this_thread::get_id() << endl;
return 0;
}
3.参考资料
https://www.cnblogs.com/haippy/p/3280643.html
https://blog.csdn.net/luoshabugui/article/details/108985042