ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

九、std::async异步线程

2021-09-17 18:02:07  阅读:180  来源: 互联网

标签:std mythread future 线程 async include


std::async、std::future创建后台任务并返回值

std::async是一个函数模板,用来启动一个异步任务,启动起来一个异步任务之后,它返回一个std::future对象,这个对象是个类模板。

 

异步任务:就是自动创建一个线程,并开始 执行对应的线程入口函数,它返回一个std::future对象,这个std::future对象中就含有线程入口函数所返回的结果,我们可以通过调用future对象的成员函数get()来获取结果。

 

“future”将来的意思,也有人称呼std::future提供了一种访问异步操作结果的机制,就是说这个结果你可能没办法马上拿到,但是在不久的将来,这个线程执行完毕的时候,你就能够拿到结果了,所以,大家这么理解:future中保存着一个值,这个值是在将来的某个时刻能够拿到。

 

std::future对象的get()成员函数会等待线程执行结束并返回结果,拿不到结果它就会一直等待,有点像join(),但它可以获取结果。

 1 #include <thread>
 2 #include <iostream>
 3 #include <list>
 4 #include <map>
 5 #include <mutex>
 6 #include <future>
 7 using namespace std;
 8 class A {
 9 public:
10     int mythread(int mypar) {
11         cout << mypar << endl;
12         return mypar;
13     }
14 };
15  
16  
17 int mythread() {
18     cout << "mythread() start" << "threadid = " << std::this_thread::get_id() << endl;
19     std::chrono::milliseconds dura(5000);
20     std::this_thread::sleep_for(dura);
21     cout << "mythread() end" << "threadid = " << std::this_thread::get_id() << endl;
22     return 5;
23 }
24  
25  
26 int main() {
27     A a;
28     int tmp = 12;
29     cout << "main" << "threadid = " << std::this_thread::get_id() << endl;
30     std::future<int> result1 = std::async(mythread);
31     cout << "主子并行........" << endl;
32     cout << result1.get() << endl; //卡在这里等待mythread()执行完毕,拿到结果,只能调用一次
33     
34     //类成员函数
35     std::future<int> result2 = std::async(&A::mythread, &a, tmp); //参数是对象引用才能保证线程里执行的是同一个对象
36     cout << result2.get() << endl;
37     cout << "good luck" << endl;
38     return 0;
39 }

通过向std::async()传递一个参数,改参数是std::launch类型(枚举类型),来达到一些特殊的目的:

1、std::lunch::deferred:

  表示线程入口函数调用被延迟到,std::future的wait()或者get()函数调用时才执行;

  如果wait()或者get()没有被调用,则不会执行。实际上根本就没有创建。(实际上延迟调用,并没有创建新线程,是在主线程中调用的线程入口函数)。

2、std::launch::async

  在调用async函数的时候就开始创建线程。async()这个函数默认用的就是std::launch::async标记。

std::packaged_task:打包任务,把任务包装起来。

类模板,它的模板参数是各种课调用对象,通过packaged_task把各种可调用对象包装起来,方便将来作为线程入口函数。(算了,不是很懂!)

 1 #include <thread>
 2 #include <iostream>
 3 #include <list>
 4 #include <map>
 5 #include <mutex>
 6 #include <future>
 7 using namespace std;
 8  
 9 int mythread(int mypar) {
10     cout << mypar << endl;
11     cout << "mythread() start" << "threadid = " << std::this_thread::get_id() << endl;
12     std::chrono::milliseconds dura(5000);
13     std::this_thread::sleep_for(dura);
14     cout << "mythread() end" << "threadid = " << std::this_thread::get_id() << endl;
15     return 5;
16 }
17  
18  
19 int main() {
20     int tmp = 12;
21     cout << "main" << "threadid = " << std::this_thread::get_id() << endl;
22     std::packaged_task<int(int)> mypt(mythread); //我们把函数mythread通过packaged_task包装起来
23     std::thread t1(std::ref(mypt), 1);
24     t1.join();
25     std::future<int> result = mypt.get_future(); 
26     //std::future对象里包含有线程入口函数的返回结果,这里result保存mythread返回的结果。
27     cout << result.get() << endl;
28     cout << "good luck" << endl;
29     return 0;
30 }

std::promise,类模板

我们能够在某个线程中给它赋值,然后我们可以在其他线程中,把这个值取出来。

 1 #include <thread>
 2 #include <iostream>
 3 #include <list>
 4 #include <map>
 5 #include <mutex>
 6 #include <future>
 7 using namespace std;
 8  
 9 void mythread(std::promise<int> &tmp, int clac) {
10     cout << "mythread() start" << "threadid = " << std::this_thread::get_id() << endl;
11     std::chrono::milliseconds dura(5000);   
12     std::this_thread::sleep_for(dura);
13     cout << "mythread() end" << "threadid = " << std::this_thread::get_id() << endl;
14     int result = clac;
15     tmp.set_value(result); //结果保存到了tmp这个对象中
16     return;
17 }
18  
19 vector<std::packaged_task<int(int)>> task_vec;
20  
21 int main() {
22     std::promise<int> myprom;
23     std::thread t1(mythread, std::ref(myprom), 180);
24     t1.join(); //在这里线程已经执行完了
25     std::future<int> fu1 = myprom.get_future(); //promise和future绑定,用于获取线程返回值
26     auto result = fu1.get();
27     cout << "result = " << result << endl;
28 }

总结:通过promise保存一个值,在将来某个时刻我们通过吧一个future绑定到这个promise上,来得到绑定的值

标签:std,mythread,future,线程,async,include
来源: https://www.cnblogs.com/zgll/p/15305754.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有