今天接著來介紹C++中幾個非同步函式
async
能讓我們用非同步的方式去調用函數,而非同步調用中也有兩種模式,參考下面例子
#include <iostream>
#include <thread>
#include <future>
#include <chrono>
using namespace std;
int CalcNum ()
{
cout << "calculatng!" << endl;
return 20;
}
int main(int argc, char const *argv[])
{
// future會是async的回傳,launch::async非同步策略會馬上執行
auto future = async(launch::async, CalcNum);
cout << "hello async " << endl;
this_thread::sleep_for(chrono::seconds(1));
cout << "answer is " << future.get() << endl;
// launch::deferred則是延遲到future變數執行wait或get才會執行
auto future2 = async(launch::deferred, CalcNum);
cout << "hello deferred " << endl;
this_thread::sleep_for(chrono::seconds(1));
cout << "answer is " << future2.get() << endl;
return 0;
}
在多線程間如果要進行數據同步或通信,promise
跟future
是一種能單向傳遞數據的方式,參考下面例子
int main(int argc, char const *argv[])
{
promise<int> pAnswer;
// 傳遞數據的子線程
auto t1 = thread([&pAnswer]
{
cout << "thread begin\n";
this_thread::sleep_for(chrono::seconds(1));
pAnswer.set_value(100);
cout << "thread end\n";
});
// 主線程等數據
cout << pAnswer.get_future().get() << endl;
t1.join();
return 0;
}
剛剛上面的future
如果get一次之後,再調用就有問題,而shared_futre
的get可以一直調用,同時也能讓多個線程共享一個future
,參考下面例子
int main(int argc, char const *argv[])
{
auto promise = std::promise<int>();
auto shared_fu = shared_future<int>(promise.get_future());
auto t2 = thread([&promise]
{
cout << "thread 2 begin\n";
this_thread::sleep_for(chrono::seconds(2));
promise.set_value(100);
cout << "thread 2 end\n";
});
auto t3 = thread([shared_fu]
{
cout << "thread 3 begin\n";
// 若promise尚未set_value就會阻塞
auto value = shared_fu.get();
cout << "thread 3 get value " << value << endl;
cout << "thread 3 end\n";
});
auto value = shared_fu.get();
cout << "main get value " << value << endl;
t2.join();
t3.join();
return 0;
}
packaged_task
能讓我們再線程之間傳遞可調用的函數,參考下面例子
int add(int a, int b)
{
return a + b;
}
int main(int argc, char const *argv[])
{
packaged_task<int(int, int)> task(add);
future<int> result = task.get_future();
thread t4(move(task), 10, 20);
cout << "result is " << result.get() << endl;
t4.join();
return 0;
}