=================================版权声明=================================
版权声明:原创文章 禁止转载
请通过右侧公告中的“联系邮箱(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并回车以便让程序继续运行)