• async和Future


    =================================版权声明=================================

    版权声明:原创文章 禁止转载 

    请通过右侧公告中的“联系邮箱(wlsandwho@foxmail.com)”联系我

    勿用于学术性引用。

    勿用于商业出版、商业印刷、商业引用以及其他商业用途。                   

    本文不定期修正完善。

    本文链接:https://www.cnblogs.com/wlsandwho/p/13837290.html

    耻辱墙:http://www.cnblogs.com/wlsandwho/p/4206472.html

    =======================================================================

    C++ 异步

    =======================================================================

    如果可能,创建一个线程执行DoSomething(1),

    根据被执行函数的实际耗时,res=f.get()+res2会有不同行为,

    但最终都会执行。

    注意:

    1 async支持显式的发射策略,虽然指明async策略可以不用再调用get,但是为了统一和更明确,调一下也无妨,万一根据代码量评估绩效呢。

    2 一个future对象的get方法只能被调用一次,之后的调用是无效的。(用valid方法检测)

    但是wait方法可以调用多次。(但是不返回结果,需要再调用get。)

    3 wait_for和wait_until不会让defferred的任务启动

    4 wait和get一定会让任务启动并完成。

      1 // AsyncAndFuture.cpp : 定义控制台应用程序的入口点。
      2 //
      3 #include "stdafx.h"
      4 #include <windows.h>
      5 
      6 #include <iostream>
      7 #include <future>
      8 
      9 //////////////////////////////////////////////////////////////////////////
     10 int DoSomething(int n)
     11 {
     12     //模拟功能的函数
     13     Sleep(n * 1000);
     14 
     15     return n;
     16 }
     17 
     18 int DoSomethingWithMagic(int n)
     19 {
     20     //模拟功能的函数
     21     Sleep(n * 999);
     22 
     23     return n;
     24 }
     25 
     26 int DoSomethingWithShow(int n)
     27 {
     28     //模拟功能的函数
     29     std::cout << "Do
    ";
     30     Sleep(n * 1000);
     31     std::cout << "Done
    ";
     32 
     33     return n;
     34 }
     35 
     36 int DoSomethingByVal(int i,const std::shared_future<int>& sf)
     37 {
     38     int val = sf.get();
     39 
     40     return i + val;
     41 }
     42 
     43 //////////////////////////////////////////////////////////////////////////
     44 void Test1()
     45 {
     46     //基本用法
     47 
     48     std::future<int> f = std::async(DoSomething, 1);
     49 
     50     int res2 = DoSomething(2);
     51 
     52     int res = f.get() + res2;
     53 
     54     std::cout << res << std::endl;
     55 }
     56 
     57 //////////////////////////////////////////////////////////////////////////
     58 void Test2()
     59 {
     60     //发射策略
     61 
     62     //std::future<int> f = std::async(std::launch::async,DoSomething,1);
     63     //std::future<int> f = std::async(std::launch::deferred,DoSomething,1);
     64 }
     65 
     66 //////////////////////////////////////////////////////////////////////////
     67 void Test3()
     68 {
     69     //缓式求值
     70 
     71     auto f1 = std::async(std::launch::deferred, DoSomething, 1);
     72     auto f2 = std::async(std::launch::deferred, DoSomething, 2);
     73 
     74     bool bWhich = true;
     75     auto res = bWhich ? f1.get() : f2.get();
     76     std::cout << res << std::endl;
     77 }
     78 
     79 //////////////////////////////////////////////////////////////////////////
     80 void Test4()
     81 {
     82     //wait可调用多次,get只能调用一次
     83 
     84     auto f1 = std::async(std::launch::deferred, DoSomething, 1);
     85     f1.wait();
     86     //f1.wait();//多次调用,没问题
     87     auto res=f1.get();
     88 
     89     std::cout << res << std::endl;
     90 
     91     //auto res2 = f1.get();//多次调用,此处异常
     92 }
     93 
     94 //////////////////////////////////////////////////////////////////////////
     95 void Test5()
     96 {
     97     //虽然同一个future对象的get只能调用一次,
     98     //但是给future对象赋值后,又有了新的对象,又是一条好汉,可以调用(看汇编是用的forward实现的=重载)
     99 
    100     int res = 0;
    101 
    102     std::future<int> f = std::async(DoSomething, 1);
    103     res = f.get();
    104     std::cout << res << std::endl;
    105 
    106     f = std::async(DoSomething, 2);
    107     res = f.get();
    108     std::cout << res << std::endl;
    109 }
    110 
    111 //////////////////////////////////////////////////////////////////////////
    112 class CBestRest
    113 {
    114 public:
    115     std::future<int> f;
    116 };
    117 
    118 CBestRest oBR;
    119 
    120 void Test6()
    121 {
    122     //投机性运行,选取有限时间内最好的结果
    123 
    124     int res = 0;
    125 
    126     //尝试用一种方法得到精确解
    127     auto deadline = std::chrono::system_clock::now() + std::chrono::seconds(3);
    128     oBR.f = std::async(DoSomethingWithMagic, 5);
    129 
    130     //规规矩矩的解,不是很精确
    131     int resguess = DoSomething(2);
    132 
    133     //时间到了,算出精确解就用,万一精确解没算完,我们就用普通的解
    134     std::future_status fs = oBR.f.wait_until(deadline);
    135     if (fs==std::future_status::ready)
    136     {
    137         res = oBR.f.get();
    138     }
    139     else
    140     {
    141         res = resguess;
    142     }
    143 
    144     std::cout << res << std::endl;
    145 }
    146 
    147 //////////////////////////////////////////////////////////////////////////
    148 void Test7()
    149 {
    150     //使用shared_future,多次调用get
    151 
    152     std::shared_future<int> sf = std::async(std::launch::async, DoSomething, 5);
    153 
    154     auto f1 = std::async(DoSomethingByVal, 1, sf);
    155     auto f2 = std::async(DoSomethingByVal, 2, sf);
    156     auto f3 = std::async(DoSomethingByVal, 3, sf);
    157 
    158     //这三行是顺序的,这里是在等结果,因为它们的耗时以最大的那个为准,所以还是可以看作并行的。
    159     int res1 = f1.get();
    160     int res2 = f2.get();
    161     int res3 = f3.get();
    162 
    163     std::cout    << res1 << std::endl
    164                 << res2 << std::endl
    165                 << res3 << std::endl;
    166 }
    167 
    168 //////////////////////////////////////////////////////////////////////////
    169 void Test8()
    170 {
    171     //wait_for不会启动任务(wait_until同理)
    172     std::future<int> f = std::async(std::launch::deferred,DoSomethingWithShow, 2);
    173     std::future_status fs = f.wait_for(std::chrono::seconds(1));
    174 
    175     if (fs==std::future_status::deferred)
    176     {
    177         std::cout << "Did not Run for deferred
    ";
    178     }
    179 
    180     getchar();
    181 
    182     //任务超时的例子
    183     std::future<int> f2 = std::async(std::launch::async, DoSomethingWithShow, 2);
    184     std::future_status fs2 = f2.wait_for(std::chrono::seconds(1));
    185 
    186     if (fs2 == std::future_status::timeout)
    187     {
    188         std::cout << "Run but timeout
    ";
    189     }
    190 }
    191 
    192 
    193 int main()
    194 {
    195     Test1();
    196     Test2();
    197     Test3();
    198     Test4();
    199     Test5();
    200     Test6();
    201     Test7();
    202     Test8();
    203 
    204     getchar();
    205 
    206     return 0;
    207 }

    运行结果(Test8输入了一个a并回车以便让程序继续运行)

  • 相关阅读:
    iis部署网站打不开
    微信小程序全选多选效果
    清除浮动
    IIS_常见问题及解决方法
    文字闪烁效果
    IIS 伪静态 脚本映射 配置方法
    批量删除QQ空间说说
    自定义input文件上传 file的提示文字及样式
    使用google api material icons在网页中插入图标
    jquery日期插件jquery.datePicker参数
  • 原文地址:https://www.cnblogs.com/wlsandwho/p/13837290.html
Copyright © 2020-2023  润新知