1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| #include <future> #include <iostream> #include <stdexcept>
int fn(int n) { if (n < 1) throw std::invalid_argument("n < 1"); if (n < 3) return 1; return fn(n - 1) + fn(n - 2); }
int main() { try { auto fut = std::async(fn, 20); std::cout << std::boolalpha; int res = fut.get(); std::cout << "fn(20) = " << res << std::endl; auto fut2 = std::async(fn, -20); res = fut2.get(); std::cout << "fn(-20) = " << res << std::endl; } catch (const std::invalid_argument& e) { std::cerr << e.what() << std::endl; }
try { std::thread t(fn, -20); t.join(); } catch (const std::invalid_argument& e) { std::cerr << e.what() << std::endl; } }
|
可以看到,不能捕获std::thread中抛出的异常。但std::async可以通过std::promise/std::future设置/捕获异常。
另外,std::async未必真的异步,如有必要可以指定std::launch::async
1 2 3 4 5 6 7 8 9 10
| template <typename F, typename... Ts> inline std::future<typename std::result_of<F(Ts...)>::type> reallyAsync(F&& f, Ts&&...params) { return std::async(std::launch::async, std::forward<F>(f), std::forward<Ts>(params)...); }
template <typename F, typename... Ts> inline auto reallyAsync(F&& f, Ts&&...params) { return std::async(std::launch::async, std::forward<F>(f), std::forward<Ts>(params)...); }
|