怎么在C++11中使用std::async方法

本篇文章给大家分享的是有关怎么在C++11中使用std::async方法,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。

std::async有两个版本:

1.无需显示指定启动策略,自动选择,因此启动策略是不确定的,可能是std::launch::async,也可能是std::launch::deferred,或者是两者的任意组合,取决于它们的系统和特定库实现。

2.允许调用者选择特定的启动策略。

std::async的启动策略类型是个枚举类enum class launch,包括:

1. std::launch::async:异步,启动一个新的线程调用Fn,该函数由新线程异步调用,并且将其返回值与共享状态的访问点同步。

2. std::launch::deferred:延迟,在访问共享状态时该函数才被调用。对Fn的调用将推迟到返回的std::future的共享状态被访问时(使用std::future的wait或get函数)。

参数Fn:可以为函数指针、成员指针、任何类型的可移动构造的函数对象(即类定义了operator()的对象)。Fn的返回值或异常存储在共享状态中以供异步的std::future对象检索。

参数Args:传递给Fn调用的参数,它们的类型应是可移动构造的。

返回值:当Fn执行结束时,共享状态的std::future对象准备就绪。std::future的成员函数get检索的值是Fn返回的值。当启动策略采用std::launch::async时,即使从不访问其共享状态,返回的std::future也会链接到被创建线程的末尾。在这种情况下,std::future的析构函数与Fn的返回同步。

std::future介绍参考:https://www.jb51.net/article/179229.htm

详细用法见下面的测试代码,下面是从其他文章中copy的测试代码,部分作了调整,详细内容介绍可以参考对应的reference:

#include "future.hpp" #include <iostream> #include <future> #include <chrono> #include <utility> #include <thread> #include <functional> #include <memory> #include <exception>  #include <numeric> #include <vector> #include <cmath> #include <string> #include <mutex>   namespace future_ {   /////////////////////////////////////////////////////////// // reference:  int test_async_1() {  auto is_prime = [](int x) {  std::cout << "Calculating. Please, wait...\n";  for (int i = 2; i < x; ++i) if (x%i == 0) return false;  return true;  };    // call is_prime(313222313) asynchronously:  std::future<bool> fut = std::async(is_prime, 313222313);    std::cout << "Checking whether 313222313 is prime.\n";  // ...    bool ret = fut.get(); // waits for is_prime to return  if (ret) std::cout << "It is prime!\n";  else std::cout << "It is not prime.\n";    return 0; }   /////////////////////////////////////////////////////////// // reference:  int test_async_2() {  auto print_ten = [](char c, int ms) {  for (int i = 0; i < 10; ++i) {   std::this_thread::sleep_for(std::chrono::milliseconds(ms));   std::cout << c;  }  };    std::cout << "with launch::async:\n";  std::future<void> foo = std::async(std::launch::async, print_ten, '*', 100);  std::future<void> bar = std::async(std::launch::async, print_ten, '@', 200);  // async "get" (wait for foo and bar to be ready):  foo.get(); // 注:注释掉此句,也会输出'*'  bar.get();  std::cout << "\n\n";    std::cout << "with launch::deferred:\n";  foo = std::async(std::launch::deferred, print_ten, '*', 100);  bar = std::async(std::launch::deferred, print_ten, '@', 200);  // deferred "get" (perform the actual calls):  foo.get(); // 注:注释掉此句,则不会输出'**********'  bar.get();  std::cout << '\n';    return 0; }   /////////////////////////////////////////////////////////// // reference: https://en.cppreference.com/w/cpp/thread/async std::mutex m;   struct X {  void foo(int i, const std::string& str) {  std::lock_guard<std::mutex> lk(m);  std::cout << str << ' ' << i << '\n';  }  void bar(const std::string& str) {  std::lock_guard<std::mutex> lk(m);  std::cout << str << '\n';  }  int operator()(int i) {  std::lock_guard<std::mutex> lk(m);  std::cout << i << '\n';  return i + 10;  } };   template <typename RandomIt> int parallel_sum(RandomIt beg, RandomIt end) {  auto len = end - beg;  if (len < 1000)  return std::accumulate(beg, end, 0);    RandomIt mid = beg + len / 2;  auto handle = std::async(std::launch::async, parallel_sum<RandomIt>, mid, end);  int sum = parallel_sum(beg, mid);  return sum + handle.get(); }   int test_async_3() {  std::vector<int> v(10000, 1);  std::cout << "The sum is " << parallel_sum(v.begin(), v.end()) << '\n';    X x;  // Calls (&x)->foo(42, "Hello") with default policy:  // may print "Hello 42" concurrently or defer execution  auto a1 = std::async(&X::foo, &x, 42, "Hello");  // Calls x.bar("world!") with deferred policy  // prints "world!" when a2.get() or a2.wait() is called  auto a2 = std::async(std::launch::deferred, &X::bar, x, "world!");  // Calls X()(43); with async policy  // prints "43" concurrently  auto a3 = std::async(std::launch::async, X(), 43);  a2.wait();           // prints "world!"  std::cout << a3.get() << '\n'; // prints "53"    return 0; } // if a1 is not done at this point, destructor of a1 prints "Hello 42" here   /////////////////////////////////////////////////////////// // reference: https://thispointer.com/c11-multithreading-part-9-stdasync-tutorial-example/ int test_async_4() {  using namespace std::chrono;    auto fetchDataFromDB = [](std::string recvdData) {  // Make sure that function takes 5 seconds to complete  std::this_thread::sleep_for(seconds(5));  //Do stuff like creating DB Connection and fetching Data  return "DB_" + recvdData;  };    auto fetchDataFromFile = [](std::string recvdData) {  // Make sure that function takes 5 seconds to complete  std::this_thread::sleep_for(seconds(5));  //Do stuff like fetching Data File  return "File_" + recvdData;  };    // Get Start Time  system_clock::time_point start = system_clock::now();    std::future<std::string> resultFromDB = std::async(std::launch::async, fetchDataFromDB, "Data");    //Fetch Data from File  std::string fileData = fetchDataFromFile("Data");    //Fetch Data from DB  // Will block till data is available in future<std::string> object.  std::string dbData = resultFromDB.get();    // Get End Time  auto end = system_clock::now();  auto diff = duration_cast <std::chrono::seconds> (end - start).count();  std::cout << "Total Time Taken = " << diff << " Seconds" << std::endl;    //Combine The Data  std::string data = dbData + " :: " + fileData;  //Printing the combined Data  std::cout << "Data = " << data << std::endl;    return 0; }   } // namespace future_

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。