当前位置:   article > 正文

c++11:std::async、std::launch_为什么执行 auto f = std::async(std::launch::async 没有立即返

为什么执行 auto f = std::async(std::launch::async 没有立即返回

1、std::async

unspecified policy (1)
template <class Fn, class... Args>
  future<typename result_of<Fn(Args...)>::type>
    async (Fn&& fn, Args&&... args);
specific policy (2)
template <class Fn, class... Args>
  future<typename result_of<Fn(Args...)>::type>
    async (launch policy, Fn&& fn, Args&&... args);

Call function asynchronously
Calls fn (with args as arguments) at some point, returning without waiting for the execution of fn to complete.

The value returned by fn can be accessed through the future object returned (by calling its member future::get).

The second version (2) lets the caller select a specific launching policy, while the first version (1) uses automatic selection, as if calling (2) with launch::async|launch::deferred as policy.

The function temporarily stores in the shared state either the threading handler used or decay copies of fn and args (as a deferred function) without making it ready. Once the execution of fn is completed, the shared state contains the value returned by fn and is made ready.

example:

  1. // async example
  2. #include <iostream> // std::cout
  3. #include <future> // std::async, std::future
  4. // a non-optimized way of checking for prime numbers:
  5. bool is_prime (int x) {
  6. std::cout << "Calculating. Please, wait...\n";
  7. for (int i=2; i<x; ++i) if (x%i==0) return false;
  8. return true;
  9. }
  10. int main ()
  11. {
  12. // call is_prime(313222313) asynchronously:
  13. std::future<bool> fut = std::async (is_prime,313222313);
  14. std::cout << "Checking whether 313222313 is prime.\n";
  15. // ...
  16. bool ret = fut.get(); // waits for is_prime to return
  17. if (ret) std::cout << "It is prime!\n";
  18. else std::cout << "It is not prime.\n";
  19. return 0;
  20. }

output:

std::async开一个线程去执行is_prime()。默认不等待继续执行,std::future<bool>类型的fut接收返回值(用get()获取)

2、std::launch

A bitmask value of type launch indicating the launching policy:

policydescription
launch::asyncAsynchronous: Launches a new thread to call fn (as if a thread object is constructed with fn and args as arguments, and accessing the shared state of the returned future joins it).
launch::deferredDeferred: The call to fn is deferred until the shared state of the returned future is accessed (with wait or get). At that point, fn is called and the function is no longer considered deferred. When this call returns, the shared state of the returned future is made ready.
launch::async|launch::deferredAutomatic: The function chooses the policy automatically (at some point). This depends on the system and library implementation, which generally optimizes for the current availability of concurrency in the system.

example:

  1. // launch::async vs launch::deferred
  2. #include <iostream> // std::cout
  3. #include <future> // std::async, std::future, std::launch
  4. #include <chrono> // std::chrono::milliseconds
  5. #include <thread> // std::this_thread::sleep_for
  6. void print_ten (char c, int ms) {
  7. for (int i=0; i<10; ++i) {
  8. std::this_thread::sleep_for (std::chrono::milliseconds(ms));
  9. std::cout << c;
  10. }
  11. }
  12. int main ()
  13. {
  14. std::cout << "with launch::async:\n";
  15. std::future<void> foo = std::async (std::launch::async,print_ten,'*',100);
  16. std::future<void> bar = std::async (std::launch::async,print_ten,'@',200);
  17. // async "get" (wait for foo and bar to be ready):
  18. foo.get();
  19. bar.get();
  20. std::cout << "\n\n";
  21. std::cout << "with launch::deferred:\n";
  22. foo = std::async (std::launch::deferred,print_ten,'*',100);
  23. bar = std::async (std::launch::deferred,print_ten,'@',200);
  24. // deferred "get" (perform the actual calls):
  25. foo.get();
  26. bar.get();
  27. std::cout << '\n';
  28. return 0;
  29. }

output:

compare:

std::launch::deferred:那么线程的执行就会推迟到std::future.get()方法时才会启动,如果不使用get或者wait时,线程直到结束也不会去执行fn,还有一点是在get()之前彻底就没开辟新线程。

std::launch::async:声明的时候就会去创建新线程(系统默认使用的就是这个参数)。和无std::launch::async的std::async不一样的地方是无std::launch::async的std::async需要手动去get()去等待线程结束,而std::launch::async会自动阻塞等待完成。如果在不需要返回值的情况下使用std::launch::asynch会更方便。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/602451
推荐阅读
相关标签
  

闽ICP备14008679号