先上代码体会
#include <iostream>
#include <future>
#include <chrono>
using namespace std;
// 定义一个会返回5的函数
int fun(char c) {
// 循环输出字符
for (int i = 0; i < 20; ++i) {
cout << c;
this_thread::sleep_for(chrono::microseconds(50));
// this_thread::yield();
}
return 5;
}
int main() {
// 准备后台调用
future<int> f = async(launch::any, fun, '+');
cout << fun('-') + f.get(); // 调用
cout << endl;
}
结果
-±±+±±±±±-±+±±±±±±±-±±+10
分析结果
可以看出在代码25行计算的时候需要调用两次fun
函数,如果是串行的话,那么两种符号不会交替出现,两种符号不规则的交替出现正是并行的结果。
函数讲解
-
future<returnType>
部分包含在头文件<future>
中,其中returnType
是并行子函数的返回类型,如果没有返回值那么应该设为void
,当然f
左半部分可以用auto
来进行类型推倒。- 要调用这个实例就用
f.get()
,当然这牵扯到模式,见下一条。
- 要调用这个实例就用
-
async(launch __policy, _Fp&& __f, _Args&&... __args)
函数用来后台开启一个线程。- 第一个参数可选为
launch::async
强制开启一个线程,若无法开启会报错。launch::deferred
为必须要后期对f实例进行get()
调用才会执行这个线程。launch::any
这个选项就神奇了,标准库文档中也没提到,是笔者在源码中看到的,歧视async可以只接收一个函数名——即函数地址来开启线程,但是这样就无法使得子函数接受参数,所以这个any是理解为默认?any在源码中的定义为前两者标识位相或——any = async | deferred
。这里用any也是因为强迫症,因为不想开不了线程就报错,也不想用deferred
导致串行,大胆猜测这是标准库为了这样传递参数的妥协?
- 第二个参数为调用的子函数地址,即函数名
- 第三个参数为子函数需要的参数
- 第一个参数可选为