まず、std :: async関数のプロトタイプを見てみましょう。
template<class Fn, class... Args>
future<typename result_of<Fn(Args...)>::type> async(launch policy, Fn&& fn, Args&&...args);
asyncには3つのパラメーターがあり、最初のパラメーターはデータ相互作用モードを設定するために使用され、2番目のパラメーターは呼び出し可能なオブジェクト(関数、ラムダ式、クラスメンバー関数、通常の関数...)であり、 3番目の最初のパラメーターは、2番目のパラメーターの関数パラメーターです。
データの相互作用方法が同期であるか非同期であるかは、最初のパラメーターによって決定されます。
- std :: launch :: asyncによって渡された呼び出し可能オブジェクトは、非同期で実行されます。
- std :: launch :: deferredによって渡された呼び出し可能オブジェクトは、同期的に実行されます。
- std :: launch :: async | std :: launch :: deferredは、オペレーティングシステムに応じて、非同期または同期にすることができます。制御はできません。
- 戦略を指定しない場合は、(3)と同等です。
実行結果については、get、wait、wait_for、wait_untilを使用して、実行が終了するのを待つことができます。違いは、getが実行結果を取得できることです。非同期実行戦略が選択されている場合、getが呼び出されたときに非同期実行が終了しないと、getは非同期実行が終了して結果が取得されるまで、現在の呼び出しスレッドをブロックします。非同期実行が終了した場合、getは実行しません。実行結果の取得を待機します。同期実行戦略が選択されている場合は、get関数が呼び出されたときにのみ、同期呼び出しが実際に実行されます。これは、関数呼び出しの遅延とも呼ばれます。
返された結果のステータスstd :: future:
- 延期:非同期操作はまだ開始されていません。
- 準備完了:非同期操作が完了しました。
- タイムアウト:非同期操作のタイムアウト。
例1
#include <iostream>
#include <string>
#include <chrono>
#include <thread>
#include <future>
using namespace std::chrono;
std::string fetchDataFromDB(std::string recvData) {
std::cout << "fetchDataFromDB start " << std::this_thread::get_id() << std::endl;
std::this_thread::sleep_for(seconds(5));
return "DB_" + recvData;
}
std::string fetchDataFromFile(std::string recvData) {
std::cout << "fetchDataFromFile start " << std::this_thread::get_id() << std::endl;
std::this_thread::sleep_for(seconds(3));
return "File_" + recvData;
}
int main() {
std::cout << "main start" << std::this_thread::get_id() << std::endl;
//获取开始时间
system_clock::time_point start = system_clock::now();
std::future<std::string> resultFromDB = std::async(std::launch::async, fetchDataFromDB, "Data");
//从文件获取数据
std::future<std::string> fileData = std::async(std::launch::deferred, fetchDataFromFile, "Data");
//知道调用get函数fetchDataFromFile才开始执行
std::string FileData = fileData.get();
//如果fetchDataFromDB()执行没有完成,get会一直阻塞当前线程
std::string dbData = resultFromDB.get();
//获取结束时间
auto end = system_clock::now();
auto diff = duration_cast<std::chrono::seconds>(end - start).count();
std::cout << "Total Time taken = " << diff << " Seconds. " << std::endl;
//组装数据
std::string data = dbData + " :: " + FileData;
//输出组装的数据
std::cout << "Data = " << data << std::endl;
return 0;
}
例2
#include <iostream>
#include <string>
#include <chrono>
#include <thread>
#include <future>
using namespace std::chrono;
std::string fetchDataFromDB(std::string recvData) {
std::cout << "fetchDataFromDB start " << std::this_thread::get_id() << std::endl;
std::this_thread::sleep_for(seconds(5));
return "DB_" + recvData;
}
int main() {
std::cout << "main start" << std::this_thread::get_id() << std::endl;
//获取开始时间
system_clock::time_point start = system_clock::now();
std::future<std::string> resultFromDB = std::async(std::launch::async, fetchDataFromDB, "Data");
std::future_status status;
std::string dbData;
do
{
status = resultFromDB.wait_for(std::chrono::seconds(1));
switch (status)
{
case std::future_status::ready:
std::cout << "Ready..." << std::endl;
//获取结果
dbData = resultFromDB.get();
std::cout << dbData << std::endl;
break;
case std::future_status::timeout:
std::cout << "timeout..." << std::endl;
break;
case std::future_status::deferred:
std::cout << "deferred..." << std::endl;
break;
default:
break;
}
} while (status != std::future_status::ready);
//获取结束时间
auto end = system_clock::now();
auto diff = duration_cast<std::chrono::seconds>(end - start).count();
std::cout << "Total Time taken = " << diff << " Seconds. " << std::endl;
return 0;
}