Thread和Promise以及packaged_task

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

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

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

勿用于学术性引用。

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

本文不定期修正完善。

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

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

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

C++ 异步

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

thread的join是阻塞的,detach是放弃管理(不阻塞),必须调用两者中的一个。

thread永远是创建时启动(除非异常)

promise和future配合使用(promise的get_future只能调用一次)

packaged_task是可以通过reset来重复使用(但是如果之前的任务未完成会异常)。并不立即启动任务,在显式调用时启动。

  1 #include <iostream>
  2 
  3 #include <chrono>
  4 #include <thread>
  5 #include <future>
  6 #include <string>
  7 
  8 void DoSomethingWithPromise(std::promise<std::string>& p, int v)
  9 {
 10     std::cout << "Do
";
 11     std::this_thread::sleep_for(std::chrono::milliseconds(v * 1000));//Sleep(v*1000);
 12     std::cout << "Done
";
 13 
 14     p.set_value(std::to_string(v * 1000));
 15 }
 16 
 17 int DoSomethingbyVal(int v)
 18 {
 19     std::cout << "Do
";
 20     std::this_thread::sleep_for(std::chrono::milliseconds(v * 1000));//Sleep(v*1000);
 21     std::cout << "Done
";
 22 
 23     return v * 1000;
 24 }
 25 
 26 //////////////////////////////////////////////////////////////////////////
 27 void Test1()
 28 {
 29     //join是阻塞的
 30     std::thread t(DoSomethingbyVal, 5);
 31     std::cout << "join
";
 32     t.join();
 33     std::cout << "joined
";
 34 }
 35 
 36 //////////////////////////////////////////////////////////////////////////
 37 void Test2()
 38 {
 39     //detach是放弃管理(不阻塞)
 40     std::thread t(DoSomethingbyVal, 5);
 41     std::cout << "join
";
 42     t.detach();
 43     std::cout << "joined
";
 44 }
 45 
 46 //////////////////////////////////////////////////////////////////////////
 47 void Test3()
 48 {
 49     //利用promise获取线程函数的结果
 50     std::promise<std::string> p;
 51     std::thread t(DoSomethingWithPromise, std::ref(p), 5);
 52     std::cout << "t
";
 53     t.detach();
 54 
 55     std::future<std::string> f(p.get_future());
 56     std::cout << "f
";
 57 
 58     std::string str = f.get();
 59     std::cout << str << std::endl;
 60 }
 61 
 62 //////////////////////////////////////////////////////////////////////////
 63 void Test4()
 64 {
 65     //利用promise获取线程函数的结果,看起来这个书写顺序更好一点
 66     std::promise<std::string> p;
 67     std::future<std::string> f(p.get_future());
 68     std::cout << "f
";
 69 
 70     std::thread t(DoSomethingWithPromise, std::ref(p), 5);
 71     std::cout << "t
";
 72     t.detach();
 73 
 74     std::string str = f.get();
 75     std::cout << str << std::endl;
 76 
 77 //    getchar();
 78 //     //再次调用异常,只能使用一次
 79 //     std::future<std::string> f2(p.get_future());
 80 //     std::string str2 = f2.get();
 81 //     std::cout << str2 << std::endl;
 82 }
 83 
 84 //////////////////////////////////////////////////////////////////////////
 85 void Test5()
 86 {
 87     //稍后启动一个task
 88     std::packaged_task<int(int)> pt(DoSomethingbyVal);
 89     std::future<int> f = pt.get_future();
 90 
 91     pt(5);
 92     int res = f.get();
 93     std::cout << res << std::endl;
 94 }
 95 
 96 //////////////////////////////////////////////////////////////////////////
 97 void Test6()
 98 {
 99     //稍后启动一个task
100     std::packaged_task<int(int)> pt(DoSomethingbyVal);
101 
102     pt(5);
103     std::future<int> f = pt.get_future();//放这里也可以
104     int res = f.get();
105     std::cout << res << std::endl;
106 
107     pt.reset();//重置后可再次调用
108 
109     pt(2);
110     std::future<int> f2 = pt.get_future();
111     int res2 = f2.get();
112     std::cout << res2 << std::endl;
113 
114 }
115 
116 void Test7()
117 {
118     //重复利用task
119     std::packaged_task<int(int)> pt(DoSomethingbyVal);
120 
121     pt(5);
122     std::shared_future<int> sf1 = pt.get_future();
123     pt.reset();
124     int res11 =sf1.get();
125     std::cout << res11 << std::endl;
126     int res12 = sf1.get();
127     std::cout << res12 << std::endl;
128 
129     pt(3);
130     std::shared_future<int> sf2 = pt.get_future();
131     pt.reset();
132     int res21 = sf2.get();
133     std::cout << res21 << std::endl;
134     int res22 = sf2.get();
135     std::cout << res22 << std::endl;
136 }
137 
138 void Test8()
139 {
140     //重复利用task
141     std::packaged_task<int(int)> pt(DoSomethingbyVal);
142 
143     std::shared_future<int> sf1 = pt.get_future();//放这里也可以
144     pt(5);
145     pt.reset();
146     int res11 = sf1.get();
147     std::cout << res11 << std::endl;
148     int res12 = sf1.get();
149     std::cout << res12 << std::endl;
150 
151     std::shared_future<int> sf2 = pt.get_future();//放这里也可以
152     pt(3);
153     pt.reset();
154     int res21 = sf2.get();
155     std::cout << res21 << std::endl;
156     int res22 = sf2.get();
157     std::cout << res22 << std::endl;
158 }
159 //////////////////////////////////////////////////////////////////////////
160 
161 int main()
162 {
163     std::cout << "--------------1---------------" << std::endl;
164     Test1();
165     std::cout << "--------------2---------------" << std::endl;
166     Test2();
167     std::cout << "--------------3---------------" << std::endl;
168     Test3();
169     std::cout << "--------------4---------------" << std::endl;
170     Test4();
171     std::cout << "--------------5---------------" << std::endl;
172     Test5();
173     std::cout << "--------------6---------------" << std::endl;
174     Test6();
175     std::cout << "--------------7---------------" << std::endl;
176     Test7();
177     std::cout << "--------------8---------------" << std::endl;
178     Test8();
179     std::cout << "--------------END---------------" << std::endl;
180     getchar();
181     return 0;
182 }

运行结果

原文地址:https://www.cnblogs.com/wlsandwho/p/13837447.html