背景
现代C++提供了一些很好的特性可以让我们实现优雅、高效的异步操作,今天向大家简要地介绍一下。
std::async
std::async(std::launch::async | std::launch::deferred, f, args...)
f为需要异步执行的函数,
args为f函数的参数,
第一个参数可选,在Visiual C++中默认为std::launch::async,即创建的future对象在创建完成后立即异步执行,当第一个参数为std::launch::deferred时表示future对象延迟执行。
样例
代码
#include <iostream>
#include <future>
#include <thread>
#include <chrono>
using namespace std;
int main(){
auto future1 = async([](int &&x)->int{
auto ret = 0;
for(auto i = 0; i < x; i++){
this_thread::sleep_for(chrono::seconds(1));
ret += i;
cout << "Task 1 calculating to " << x - 1 << " and now the turn is " << i << " and the value is " << ret << endl;
}
return ret;
},10); //future1 立即异步执行
auto future2 = async([](int &&x)->int{
auto ret = 1;
for(auto i = 1; i < x + 1; i++){
this_thread::sleep_for(chrono::seconds(2));
ret *= i;
cout << "Task 2 calculating to " << x << " and now the turn is " << i << " and the value is " << ret << endl;
}
return ret;
},5); //future2 立即异步执行
std::cout << "waiting...\n";
cout << "Result of task 1: " << future1.get() << endl;
cout << "Result of task 2: " << future2.get() << endl;
}
输出
c:\Users\yixian\workspace\test>async
waiting...
Task 1 calculating to 9 and now the turn is 0 and the value is 0
Task 1 calculating to 9 and now the turn is 1 and the value is 1
Task 2 calculating to 5 and now the turn is 1 and the value is 1
Task 2 calculating to 5 and now the turn is 2 and the value is 2
Task 2 calculating to 5 and now the turn is 3 and the value is 6Task 1 calculating to 9 and now the turn is 2 and the value is 3
Task 1 calculating to 9 and now the turn is 3 and the value is 6
Task 1 calculating to 9 and now the turn is 4 and the value is 10
Task 1 calculating to 9 and now the turn is 5 and the value is 15
Task 1 calculating to 9 and now the turn is 6 and the value is 21
Task 1 calculating to 9 and now the turn is 7 and the value is 28
Task 1 calculating to 9 and now the turn is 8 and the value is 36
Task 1 calculating to 9 and now the turn is 9 and the value is 45
Task 2 calculating to 5 and now the turn is 4 and the value is 24
Task 2 calculating to 5 and now the turn is 5 and the value is 120
Result of task 1: 45
指定参数为std::launch::deffered
#include <iostream>
#include <future>
#include <thread>
#include <chrono>
using namespace std;
int main(){
auto future1 = async(launch::deferred,[](int &&x)->int{
auto ret = 0;
for(auto i = 0; i < x; i++){
this_thread::sleep_for(chrono::seconds(1));
ret += i;
cout << "Task 1 calculating to " << x - 1 << " and now the turn is " << i << " and the value is " << ret << endl;
}
return ret;
},10); //future1 并不会立即异步执行
auto future2 = async(launch::deferred,[](int &&x)->int{
auto ret = 1;
for(auto i = 1; i < x + 1; i++){
this_thread::sleep_for(chrono::seconds(2));
ret *= i;
cout << "Task 2 calculating to " << x << " and now the turn is " << i << " and the value is " << ret << endl;
}
return ret;
},5); //future2 并不会立即异步执行
std::cout << "waiting...\n";
cout << "Result of task 1: " << future1.get() << endl; //future1在此时执行
cout << "Result of task 2: " << future2.get() << endl; //futute2在此时执行
}
输出
c:\Users\yixian\workspace\test>async
waiting...
Task 1 calculating to 9 and now the turn is 0 and the value is 0
Task 1 calculating to 9 and now the turn is 1 and the value is 1
Task 1 calculating to 9 and now the turn is 2 and the value is 3
Task 1 calculating to 9 and now the turn is 3 and the value is 6
Task 1 calculating to 9 and now the turn is 4 and the value is 10
Task 1 calculating to 9 and now the turn is 5 and the value is 15
Task 1 calculating to 9 and now the turn is 6 and the value is 21
Task 1 calculating to 9 and now the turn is 7 and the value is 28
Task 1 calculating to 9 and now the turn is 8 and the value is 36
Task 1 calculating to 9 and now the turn is 9 and the value is 45
Result of task 1: 45
Task 2 calculating to 5 and now the turn is 1 and the value is 1
Task 2 calculating to 5 and now the turn is 2 and the value is 2
Task 2 calculating to 5 and now the turn is 3 and the value is 6
Task 2 calculating to 5 and now the turn is 4 and the value is 24
Task 2 calculating to 5 and now the turn is 5 and the value is 120
Result of task 2: 120