首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

[C++从零实现Json-Rpc框架]第三弹——C++11异步操作

  • 25-04-24 09:01
  • 2172
  • 7472
blog.csdn.net

一、前言

        在本篇博文中,博主将为大家带来【C++从零实现Json-Rpc框架】的第三弹,即C++11中的异步操作,希望大家能够从中有所收获

二、正文

1.std::future 介绍

std::future是C++11标准库中的⼀个模板类,它表⽰⼀个异步操作的结果。当我们在多线程编程中使⽤异步任务时,std::future可以帮助我们在需要的时候获取任务的执⾏结果。std::future的⼀个重要特性是能够阻塞当前线程,直到异步操作完成,从⽽确保我们在获取结果时不会遇到未完成的操作。

注:std::futrue 本质上不是一个异步任务,而是一个辅助我们获取异步任务结果的东西

2. 应用场景

• 异步任务:当我们需要在后台执⾏⼀些耗时操作时,如⽹络请求或计算密集型任务等,std::future 可以⽤来表⽰这些异步任务的结果。通过将任务与主线程分离,我们可以实现任务的并⾏处理,从而提⾼程序的执⾏效率

• 并发控制:在多线程编程中,我们可能需要等待某些任务完成后才能继续执⾏其他操作。通过使⽤ std::future,我们可以实现线程之间的同步,确保任务完成后再获取结果并继续执⾏后续操作

 • 结果获取:std::future提供了⼀种安全的⽅式来获取异步任务的结果。我们可以使⽤ std::future::get()函数来获取任务的结果,此函数会阻塞当前线程,直到异步操作完成。这样,在调⽤get()函数时,我们可以确保已经获取到了所需的结果

3. 用法介绍与示例

std::future并不能单独使用,需要搭配一些能够执行异步任务的模板类或者函数一起使用

异步任务搭配使用:

        ●std::async函数模版:异步执行一个函数,返回一个future对象用于获取函数结果

        ●std::packaged_task类模版:为一个函数生成一个异步任务对象(可调用对象),用于在其他线程中执行

        ●std::promi类模板:示例的对象可以返回一个对象,在其他线程中向promise对象设置数据,其他线程的关联future就可以获取数据

 ● 使用std::async关联异步任务

std::async是⼀种将任务与std::future关联的简单⽅法。它创建并运⾏⼀个异步任务,并返回⼀个与该 任务结果关联的std::future对象。默认情况下,std::async是否启动⼀个新线程,或者在等待future 时,任务是否同步运⾏都取决于你给的参数。这个参数为std::launch类型:

★ std::launch::deferred 表明该函数会被延迟调⽤,直到在future上调⽤get()或者wait()才会开始 执⾏任务

★ std::launch::async 表明函数会在⾃⼰创建的线程上运⾏ 

注: std::launch::deferred | std::launch::async内部通过系统等条件⾃动选择策略,也就是在调用async函数的时候可以通过参数的传递来选择任务执行的方式是同步还是异步。

  1. #include
  2. #include
  3. #include
  4. int Add(int num1, int num2){
  5. std::cout<
  6. return num1+num2;
  7. }
  8. int main()
  9. {
  10. //std::lauch::async策略:内部创建一个线程执行函数,函数运行结果通过future获取
  11. //std::lauch::deferred策略::同步策略,获取结果的时候再去执行任务
  12. std::future<int> res=std::async(std::launch::async,Add,11,22);//进行了一个异步非阻塞调用
  13. std::this_thread::sleep_for(std::chrono::seconds(1));
  14. std::cout<<"------------------------\n";
  15. //std::future::get() 用于获取异步任务的结果,如果还没有结果就会阻塞
  16. std::cout<get()<
  17. return 0;
  18. }

为了证明Add任务的执行确实是异步执行的我们将主线程休眠了1s,如果是异步的,那么Add会先打印出结果 ,再由主线程打印出分隔符

 

如果采取同步策略的方式,结果如下

 ● 使⽤std::packaged_task和std::future配合

        std::packaged_task就是将任务和std::feature绑定在⼀起的模板,是⼀种对任务的封装。我们可以通 过std::packaged_task对象获取任务相关联的std::feature对象,通过调⽤get_future()⽅法获得。 std::packaged_task的模板参数是函数签名。可以把std::future和std::async看成是分开的,⽽std::packaged_task则是⼀个整体

  1. #include
  2. #include
  3. #include
  4. #include
  5. int Add(int num1,int num2)
  6. {
  7. std::cout<<"into add!\n";
  8. return num1+num2;
  9. }
  10. int main()
  11. {
  12. //1. 封装任务
  13. auto task = std::make_sharedint(int,int)>>(Add);
  14. //2. 获取任务包关联的future对象
  15. std::future<int> res =task->get_future();
  16. std::thread thr([task](){
  17. (*task)(11,22);
  18. });
  19. //3. 获取结果
  20. std::cout<get()<
  21. thr.join();
  22. return 0;
  23. }

● 使⽤std::promise和std::future配合

std::promise提供了⼀种设置值的⽅式,它可以在设置之后通过相关联的std::future对象进⾏读取。换 种说法就是之前说过std::future可以读取⼀个异步函数的返回值了,但是要等待就绪,⽽std::promise 就提供⼀种⽅式⼿动让std::future就绪

  1. #include
  2. #include
  3. #include
  4. #include
  5. int Add(int num1,int num2)
  6. {
  7. std::cout<<"into add!\n";
  8. return num1+num2;
  9. }
  10. int main()
  11. {
  12. //1. 在使用的时候,就是先实例化一个指定结果的promis对象,
  13. std::promise<int> pro;
  14. //2. 通过promise对象,获取关联的future对象
  15. std::future<int> res=pro.get_future();
  16. //3. 在任意位置给promise设置数据,就可以通过关联的furture获取到这个设置的数据了
  17. std::thread thr([&pro](){
  18. int sum=Add(11,22);
  19. pro.set_value(sum);
  20. });
  21. std::cout<get()<
  22. thr.join();
  23. return 0;
  24. }

● 总结

        ①std::async是一个模版函数,内部会创建线程执行异步任务

        ②std::packaged_task是一个模板类,是一个任务包,是对一个函数进行二次封装,封装成一个可调用对象作为任务放到其他线程执行的。任务包封装好了可以在任意位置进行调用,通过关联的future来获取执行结果

        执行任务样例:

                1.封装任务

                2.执行任务

                3.通过futr获取任务执行结果

        ③std::promise是一个模板类,是对与结果的封装

                 1.在使用的时候,就是先实例化一个指定结果的promise对象

                 2.通过promise对象,获取关联的future对象

                 3.在任意位置给promise设置数据,就可以通过关联的future获得到这个设置的数据了

三、结语

到此为止,本文关于从零实现Json-RPC框架第三弹的内容到此结束了,如有不足之处,欢迎小伙伴们指出呀!

         关注我 _麦麦_分享更多干货:_麦麦_-CSDN博客

         大家的「关注❤️ + 点赞👍 + 收藏⭐」就是我创作的最大动力!谢谢大家的支持,我们下期见!!

一枚积极学习,乐于分享的苏苏子
QQ名片
注:本文转载自blog.csdn.net的_麦麦_的文章"https://blog.csdn.net/m0_73953114/article/details/147199921"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

112
数据库
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2024 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top