在 C++ 中實現(xiàn)異步調(diào)用有多種方法,以下是一些最佳實踐:
<future>
和 <thread>
庫:<future>
和 <thread>
庫提供了基本的線程和異步操作支持。通過 std::async
、std::packaged_task
和 std::promise
,您可以創(chuàng)建和管理異步任務(wù)。#include <iostream>
#include <future>
#include <thread>
int compute(int x, int y) {
return x + y;
}
int main() {
// 創(chuàng)建異步任務(wù)
std::future<int> result = std::async(compute, 2, 3);
// 在異步任務(wù)完成之前執(zhí)行其他工作
std::cout << "Waiting for computation...\n";
// 獲取異步任務(wù)的結(jié)果
int sum = result.get();
std::cout << "Computation result: " << sum << std::endl;
return 0;
}
std::jthread
和 std::future_value
:C++20 引入了 std::jthread
,它可以自動管理線程的生命周期。同時,std::future_value
可以用于封裝特定類型的未來結(jié)果。#include <iostream>
#include <future>
#include <jthread>
int compute(int x, int y) {
return x + y;
}
int main() {
// 創(chuàng)建異步任務(wù)
std::packaged_task<int(int, int)> task(compute);
std::future<int> result = task.get_future();
// 創(chuàng)建 jthread 運行異步任務(wù)
std::jthread thread(std::move(task), 2, 3);
// 在異步任務(wù)完成之前執(zhí)行其他工作
std::cout << "Waiting for computation...\n";
// 獲取異步任務(wù)的結(jié)果
int sum = result.get();
// 等待線程結(jié)束
thread.join();
std::cout << "Computation result: " << sum << std::endl;
return 0;
}
std::async
的 std::launch
策略:通過指定 std::launch
策略,您可以控制異步任務(wù)的啟動方式。例如,您可以使用 std::launch::async
和 std::launch::deferred
來指定任務(wù)立即啟動或在調(diào)用 get()
方法時啟動。#include <iostream>
#include <future>
int compute(int x, int y) {
return x + y;
}
int main() {
// 創(chuàng)建異步任務(wù),立即啟動
std::future<int> result = std::async(std::launch::async, compute, 2, 3);
// 在異步任務(wù)完成之前執(zhí)行其他工作
std::cout << "Waiting for computation...\n";
// 獲取異步任務(wù)的結(jié)果
int sum = result.get();
std::cout << "Computation result: " << sum << std::endl;
return 0;
}
避免使用全局或靜態(tài)異步任務(wù):全局或靜態(tài)異步任務(wù)可能導致資源競爭和同步問題。盡量將異步任務(wù)封裝在類或函數(shù)中,并確保正確地管理線程同步。
合理地處理異常:當異步任務(wù)拋出異常時,需要確保正確地捕獲和處理這些異常??梢允褂?std::future::get()
的重載版本來捕獲異常。
考慮使用線程池:對于大量并發(fā)任務(wù),可以考慮使用線程池來限制線程數(shù)量并提高性能。C++ 標準庫沒有提供線程池的實現(xiàn),但您可以自己實現(xiàn)或使用第三方庫(如 Intel Threading Building Blocks (TBB))。