1 详解std::async
1.1 std::async
作用
std::async
可以异步在一个独立线程中运行线程函数F
,并且返回一个存储线程函数F
运行结果的std::future
,简而言之就是C++提供的高级异步接口。
函数原型
template< class Function, class... Args >
std::future<typename std::result_of<typename std::decay<Function>::type(
typename std::decay<Args>::type...)>::type>
async( Function&& f, Args&&... args );
template< class Function, class... Args >
std::future<std::invoke_result_t<std::decay_t<Function>,
std::decay_t<Args>...>>
async( Function&& f, Args&&... args );
template< class Function, class... Args >
[[nodiscard]] std::future<std::invoke_result_t<std::decay_t<Function>,
std::decay_t<Args>...>>
async( Function&& f, Args&&... args );
template< class Function, class... Args >
std::future<typename std::result_of<typename std::decay<Function>::type(
typename std::decay<Args>::type...)>::type>
async( std::launch policy, Function&& f, Args&&... args );
template< class Function, class... Args >
std::future<std::invoke_result_t<std::decay_t<Function>,
std::decay_t<Args>...>>
async( std::launch policy, Function&& f, Args&&... args );
template< class Function, class... Args >
[[nodiscard]] std::future<std::invoke_result_t<std::decay_t<Function>,
std::decay_t<Args>...>>
async( std::launch policy, Function&& f, Args&&... args );
函数参数
std::async
主要的参数如下
f
:线程函数,可接受function, lambda expression, bind expression, or another function object-
args...
:线程函数参数 -
policy
:可选std::launch::async
和std::launch::deferred
,默认为std::launch::async | std::launch::deferred
两种策略的合集。
线程创建策略的具体含义:
- std::launch::async调度策略意味着函数必须异步执行,即在另一线程执行
- std::launch::deferred调度策略意味着函数可能只会在std::async返回的future对象调用get或wait时执行。那就是,执行会推迟到其中一个调用发生。当调用get或wait时,函数会同步执行,即调用者会阻塞直到函数运行结束。如果get或wait没有被调用,函数就绝对不会执行
- 如果没有显示指定创建策略,则默认策略为
std::launch::async | std::launch::deferred
,那么默认情况下这种行为是未定义的,有可能是std::launch::async
,也有可能是std::launch::deferred
,到底是异步执行还是惰性等待执行取决于具体的代码实现,所以如果需要异步执行的函数一定要显式指定std::launch::async
。
函数返回值
返回存储线程函数执行结果的std::future
。
std::future
提供了一种访问异步操作结果的机制,它提供了在主线程中在未来的某个时间以同步的方式获取异步函数执行的结果。
std::future
有三种状态:
- deferred:异步操作未开始
- ready:异步操作已经完成
- timeout:异步操作超时
std::future
获取结果的方式有三种:
get
:等待异步操作结束并返回结果wait
:等待异步操作结束,但没有返回值wait_for
:超时等待返回结果
1.2 std::async的使用
(1) 普通函数做线程函数
#include <iostream>
#include <future>
int sum(int start, int end)
{
int sum = 0;
for (int i = start; i < end; ++i)
{
sum += i;
}
return sum;
}
int main()
{
std::future<int> res1 = std::async(&sum, 1, 1000); // 默认线程创建策略
std::future<int> res2 = std::async(std::launch::async, &sum, 1, 1001); // async创建策略
std::future<int> res3 = std::async(std::launch::deferred, &sum, 1, 1002); // deferred创建策略
std::cout << "result1 = "<< res1.get() << std::endl;
std::cout << "result2 = " << res2.get() << std::endl;
std::cout << "result3 = " << res3.get() << std::endl;
return 0;
}
(2) lambda做线程函数
#include <iostream>
#include <future>
int main()
{
int start = 0;
int end = 1000;
std::future<int> res1 = std::async(std::launch::async,[start,end]() {
int sum = 0;
for (int i = start; i < end; ++i)
{
sum += i;
}
return sum;
});
std::cout << "result1 = " << res1.get() << std::endl;
return 0;
}
(3) std::function做线程函数
#include <iostream>
#include <future>
#include <functional>
int sum(int start, int end)
{
int sum = 0;
for (int i = start; i < end; ++i)
{
sum += i;
}
return sum;
}
int main()
{
int start = 0;
int end = 1000;
std::function<int(int, int)> f = std::bind(&sum,std::placeholders::_1, std::placeholders::_2);
std::future<int> res1 = std::async(f,start,end);
std::cout << "result1 = " << res1.get() << std::endl;
return 0;
}
参考
本文作者:StubbornHuang
版权声明:本文为站长原创文章,如果转载请注明原文链接!
原文标题:C++ – 详解std::async
原文链接:https://www.stubbornhuang.com/2950/
发布于:2024年01月12日 9:50:12
修改于:2024年01月12日 9:50:12
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
评论
52