C++11中的std::async是个模板函数。std::async异步调用函数,在某个时候以Args作为参数(可变长参数)调用Fn,无需等待Fn执行完成就可返回,返回结果是个std::future对象。Fn返回的值可通过std::future对象的get成员函数获取。一旦完成Fn的执行,共享状态将包含Fn返回的值并ready。

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://blog.csdn.net/fengbingchun/article/details/104115489

详细用法见下面的测试代码,下面是从其他文章中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: http://www.cplusplus.com/reference/future/async/
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 returnif (ret) std::cout << "It is prime!\n";else std::cout << "It is not prime.\n";return 0;
}///
// reference: http://www.cplusplus.com/reference/future/launch/
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 executionauto a1 = std::async(&X::foo, &x, 42, "Hello");// Calls x.bar("world!") with deferred policy// prints "world!" when a2.get() or a2.wait() is calledauto a2 = std::async(std::launch::deferred, &X::bar, x, "world!");// Calls X()(43); with async policy// prints "43" concurrentlyauto 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 completestd::this_thread::sleep_for(seconds(5));//Do stuff like creating DB Connection and fetching Datareturn "DB_" + recvdData;};auto fetchDataFromFile = [](std::string recvdData) {// Make sure that function takes 5 seconds to completestd::this_thread::sleep_for(seconds(5));//Do stuff like fetching Data Filereturn "File_" + recvdData;};// Get Start Timesystem_clock::time_point start = system_clock::now();std::future<std::string> resultFromDB = std::async(std::launch::async, fetchDataFromDB, "Data");//Fetch Data from Filestd::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 Timeauto 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 Datastd::string data = dbData + " :: " + fileData;//Printing the combined Datastd::cout << "Data = " << data << std::endl;return 0;
}} // namespace future_

GitHub:https://github.com/fengbingchun/Messy_Test

C++11中std::async的使用相关推荐

  1. 用C++11的std::async代替线程的创建

    转自:http://www.cnblogs.com/qicosmos/p/3534211.html c++11中增加了线程,使得我们可以非常方便的创建线程,它的基本用法是这样的: void f(int ...

  2. C++/C++11中std::string用法汇总

    C++/C++11中std::string是个模板类,它是一个标准库.使用string类型必须首先包含<string>头文件.作为标准库的一部分,string定义在命名空间std中. st ...

  3. C++11中std::packaged_task的使用

    C++11中的std::packaged_task是个模板类.std::packaged_task包装任何可调用目标(函数.lambda表达式.bind表达式.函数对象)以便它可以被异步调用.它的返回 ...

  4. C++11中std::shared_future的使用

    C++11中的std::shared_future是个模板类.与std::future类似,std::shared_future提供了一种访问异步操作结果的机制:不同于std::future,std: ...

  5. C++11中std::future的使用

    C++11中的std::future是一个模板类.std::future提供了一种用于访问异步操作结果的机制.std::future所引用的共享状态不能与任何其它异步返回的对象共享(与std::sha ...

  6. C++11之std::async使用介绍

    在C++11中有个async异步函数,其声明如下: template <class Fn, class... Args> future<typename result_of<F ...

  7. C语言中task的用法,C++11中std::packaged_task的使用详解

    C++11中的std::packaged_task是个模板类.std::packaged_task包装任何可调用目标(函数.lambda表达式.bind表达式.函数对象)以便它可以被异步调用.它的返回 ...

  8. 概率论中指数分布介绍及C++11中std::exponential_distribution的使用

    指数分布:在深度学习中,我们经常会需要一个在x=0点处取得边界点(sharp point)的分布.为了实现这一目的,我们可以使用指数分布(exponential distribution): p(x; ...

  9. 概率论中高斯分布(正态分布)介绍及C++11中std::normal_distribution的使用

    高斯分布:最常用的分布是正态分布(normal distribution),也称为高斯分布(Gaussian distribution): 正态分布N(x;μ,σ2)呈现经典的"钟形曲线&q ...

最新文章

  1. Struts1.x系列教程(5):HTML标签库
  2. ptyhon时间处理
  3. Asp.net MVC中Html.Partial, RenderPartial, Action,RenderAction 区别和用法【转发】
  4. winform 异步弹窗窗体_玩转控件:重写/重绘Dev中MessageBox弹窗控件
  5. 对象的克隆(clone方法)
  6. leetcode 5 查找最长的回文子串
  7. mysql 5.7.19 rpm下载_centos6.8 mysql5.7 rpm安装与完全卸载
  8. VBlog 纯前端博客 2018.5.15更新
  9. CSI笔记【3】:多进多出/MIMO技术
  10. Summery about show input info bar of MTK
  11. android 设置Spinner文字标题颜色 字体大小样式
  12. 报错:CMake Error at /usr/share/cmake-3.10/Modules/CMakeDetermineCCompiler.cmake:48 (message):
  13. 入手评测 戴尔游匣G15锐龙版 怎么样
  14. 微信小程序开发:集成腾讯地图的步骤
  15. 记一次Maven发布Jar包中文乱码解决方法
  16. 如何在 FlowUs、Notion 等笔记软件中进行时间管理?
  17. 猎豹掌门人出走,傅盛的“梦游”该醒醒了
  18. java.io.IOException: unexpected end of stream on https://xxx.xxx.xxx.xxx:84/
  19. python tkinter库 密码实时显示_python tkinter库实现气泡屏保和锁屏
  20. lpv4dns服务器怎么修改,如何修改ipv4 wins 服务器地址

热门文章

  1. Python压缩目录文件夹,解压目录文件夹及耗时效率统计
  2. ros web_video_server的使用及Python获取实时画面
  3. c++之openGL在VS中的配置及简单图形绘制
  4. c++创建包含opencv的dll供C,C#调用
  5. smali to java_Smali —— 数学运算,条件判断,循环
  6. 【骚气的动效】外发光涟漪波纹动画、向外辐射动画效果,通常用于地图上面某一个扩散点效果
  7. 喂~讲真~我很讨厌chrome谷歌浏览器的默认填充输入框input样式咧,敲击讨厌滴啦,怎么去掉介个样式尼
  8. FFMPEG转码常用命令研究
  9. UE4场景设计学习教程
  10. c4d+ps打造抽象NFT加密艺术 Create Abstract NFT Crypto Art with Cinema 4D + Photoshop