它是 c++
标准库提供的 API
,用于异步(创建单独的线程)或同步(正常调用函数)执行任务(作为参数传递)。 这取决于启动策略。
参数
f
要调用的可调用 (Callable
) 对象args
传递给f
的参数policy
位掩码值,每个单独位控制允许的执行方法
位 | 解释 |
---|---|
std::launch::async | 启用异步求值,运行新线程,以异步执行任务 |
std::launch::deferred | 启用惰性求值,在调用线程上执行任务(惰性求值)。在对 future 调用 get 和 wait 的时候,才进行执行。如果什么都没有发生,那么执行函数就没有运行。 |
launch::async|launch::deferred | 这是自动的,该函数在特定点自动选择策略。 这取决于系统以及库实现,这通常针对系统中当前的并发可用性进行优化 |
注:不使用策略参数调用 async(f, 1, 2, 3) ,我们将会选择都是用的策略。 async 的实现可以自由的选择策略。这也就意味着,我们不能确定任务会执行在一个新的线程上,还是执行在当前线程上。
启动策略
启动策略是 std::async API
的一部分,它作为第一个参数传递。 共有三种启动策略 :
- std::launch::async
- std::launch::deferred
- 默认策略(std::launch::async | std::launch::deferred)
std::launch::async
它将函数作为 单独的线程 启动,如果资源不可用,那么我们将得到异常(std::system_error
错误 std::resource::unavailable_try_again
)。
例子:
//创建单独的线程
std::future<int>result1=std::async(std::launch::async,AddThread,3,3);
std::launch::deferred
它将函数作为 同步调用 当调用 future
的 get()
或 wait()
时 启动。 如果有人使用延迟策略启动异步并且不调用 future
的 get()
或 wait()
,那么函数将永远不会启动 。
例子:
//Using std::launch::deferred policy, no separate thread.
auto result2 = std::async(std::launch::deferred, MulThread, 3, 3);
默认策略
它是上述两种策略的组合或留空(请查看下面的示例),它以异步方式(创建单独的线程)或同步方式(正常调用函数)启动函数,它取决于库,库将选择基于上述策略之一关于资源的可用性。
例子:
//Using Default Policy
//Both below function signature are same, we can use anyone.
std::async(std::launch::async|std::launch::deferred, AddThread, 6, 6);
or
std::async(AddThread, 6, 6);
综合示例
- 示例1:
#include <future>
#include <iostream>
// 检查它是否是质数
// 参数是必须检查的数字
bool fnprime(int num) {
std::cout << "处理开始。。。请等待。。。\n";
int i = 1;
while (1) {
std::cout << "处理数值" << num << " " << i << std::endl;
i++;
if (i > 100) {
break;
}
}
for (; i < num + 100; ++i) {
// 如果 mod 为0,返回 false,否则返回0
std::cout << "处理数值" << num << " " << i << std::endl;
}
return true;
}
// main method
int main() {
int num = 20;
// 异步调用函数 fnprime ()检查数字是否为质数:
std::future<bool> fobj = std::async(std::launch::async, [&]() -> bool {
std::cout << "处理开始。。。请等待。。。\n";
int i = 1;
while (1) {
std::cout << "处理数值" << num << " " << i << std::endl;
i++;
if (i > 100) {
break;
}
}
for (; i < num + 100; ++i) {
// 如果 mod 为0,返回 false,否则返回0
std::cout << "处理数值" << num << " " << i << std::endl;
}
return true;
});
// 打印该行以显示状态
std::cout << "检查数字4是否为质数 . . \n";
// 等待函数 fnPrime 返回
// bool bobj = fobj.get();
if (true)
std::cout << "给出的数字是质数 . . . ! \n";
else
std::cout << "给出的数字不是质数 . . . ! \n\n";
return 0;
}
g++ -std=c++11 -pthread ...
检查数字4是否为质数 . .
给出的数字是质数 . . . !
处理开始。。。请等待。。。
处理数值20 1
处理数值20 2
...
- 示例2
// library for std::cout
#include <iostream>
// library for std::async and std::future
#include <future>
// library for std::string
#include <string>
std::string samplefunction(const std::string& st) {
return "This is the output of " + st;
}
class SamplefunctionObject {
public:
std::string operator()(const std::string& st) const {
return "This is the output of " + st;
}
};
int main() {
std::cout << std::endl;
// future with the help of function
auto ff = std::async(samplefunction, "sample function");
// future with the help of function object
SamplefunctionObject samplefunctionObject;
auto ffo = std::async(samplefunctionObject, "sample function object");
// future with the help of lambda function
auto fl = std::async(
[](const std::string& st) { return "This is the output of " + st; },
" lambda function");
std::cout << ff.get() << "\n" << ffo.get() << "\n" << fl.get() << std::endl;
std::cout << std::endl;
}
This is the output of sample function
This is the output of sample function object
This is the output of lambda function