【Boost】boost库asio详解1——strand与io_service区别

2024-06-15 01:58

本文主要是介绍【Boost】boost库asio详解1——strand与io_service区别,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

转载于http://blog.csdn.net/huang_xw/article/details/8469851

[cpp]  view plain copy print ?
  1. namespace  
  2. {  
  3.     // strand提供串行执行, 能够保证线程安全, 同时被post或dispatch的方法, 不会被并发的执行.   
  4.     // io_service不能保证线程安全  
  5.     boost::asio::io_service m_service;  
  6.     boost::asio::strand m_strand(m_service);  
  7.     boost::mutex m_mutex;  
  8.   
  9.     void print(int id)  
  10.     {  
  11.         // boost::mutex::scoped_lock lock(m_mutex);  
  12.         static int count = 0;  
  13.         PRINT_DEBUG("id: " << boost::lexical_cast<std::string>(id));  
  14.         PRINT_DEBUG("count: " << boost::lexical_cast<std::string>(++count));  
  15.     }  
  16.       
  17.     void ioRun1()  
  18.     {  
  19.         while(true)  
  20.         {  
  21.             m_service.run();  
  22.         }  
  23.     }  
  24.   
  25.     void ioRun2()  
  26.     {  
  27.         while(true)  
  28.         {  
  29.             m_service.run();  
  30.         }  
  31.     }  
  32.   
  33.     void strand_print1()  
  34.     {  
  35.         // PRINT_DEBUG("Enter print1");  
  36.         m_strand.dispatch(boost::bind(print, 1));  
  37.         // PRINT_DEBUG("Exit print1");  
  38.     }  
  39.   
  40.     void strand_print2()  
  41.     {  
  42.         // PRINT_DEBUG("Enter print2");  
  43.         m_strand.post(boost::bind(print, 2));  
  44.         // PRINT_DEBUG("Exit print2");  
  45.     }  
  46.   
  47.     void strand_print3()  
  48.     {  
  49.         // PRINT_DEBUG("Enter print3");                
  50.         m_strand.post(boost::bind(print, 3));  
  51.         // PRINT_DEBUG("Exit print3");  
  52.     }  
  53.   
  54.     void strand_print4()  
  55.     {  
  56.         // PRINT_DEBUG("Enter print4");  
  57.         m_strand.post(boost::bind(print, 4));  
  58.         // PRINT_DEBUG("Exit print4");  
  59.     }  
  60.   
  61.     // 将上面的m_strand换成m_service后,  
  62.     void service_print1()  
  63.     {  
  64.         // PRINT_DEBUG("Enter print1");  
  65.         m_service.dispatch(boost::bind(print, 1));  
  66.         // PRINT_DEBUG("Exit print1");  
  67.     }  
  68.   
  69.     void service_print2()  
  70.     {  
  71.         // PRINT_DEBUG("Enter print2");  
  72.         m_service.post(boost::bind(print, 2));  
  73.         // PRINT_DEBUG("Exit print2");  
  74.     }  
  75.   
  76.     void service_print3()  
  77.     {  
  78.         // PRINT_DEBUG("Enter print3");                
  79.         m_service.post(boost::bind(print, 3));  
  80.         // PRINT_DEBUG("Exit print3");  
  81.     }  
  82.   
  83.     void service_print4()  
  84.     {  
  85.         // PRINT_DEBUG("Enter print4");  
  86.         m_service.post(boost::bind(print, 4));  
  87.         // PRINT_DEBUG("Exit print4");  
  88.     }  
  89. }  
  90.   
  91. void test_strand()  
  92. {  
  93.     boost::thread ios1(ioRun1);  
  94.     boost::thread ios2(ioRun2);  
  95.       
  96.     boost::thread t1(strand_print1);  
  97.     boost::thread t2(strand_print2);  
  98.     boost::thread t3(strand_print3);  
  99.     boost::thread t4(strand_print4);  
  100.   
  101.     t1.join();  
  102.     t2.join();  
  103.     t3.join();  
  104.     t4.join();  
  105.   
  106.     m_server.run();  
  107. }  
  108.   
  109. void test_service()  
  110. {  
  111.     boost::thread ios1(ioRun1);  
  112.     boost::thread ios2(ioRun2);  
  113.   
  114.     boost::thread t1(service_print1);  
  115.     boost::thread t2(service_print2);  
  116.     boost::thread t3(service_print3);  
  117.     boost::thread t4(service_print4);  
  118.       
  119.     t1.join();  
  120.     t2.join();  
  121.     t3.join();  
  122.     t4.join();  
  123.       
  124.     m_service.run();  
  125. }  
test_strand的执行结果:
[cpp]  view plain copy print ?
  1. 2013-01-05 17:25:34 626 [8228] DEBUG - id: 4  
  2. 2013-01-05 17:25:34 631 [8228] DEBUG - count: 1  
  3. 2013-01-05 17:25:34 634 [5692] DEBUG - id: 1  
  4. 2013-01-05 17:25:34 637 [5692] DEBUG - count: 2  
  5. 2013-01-05 17:25:34 640 [5692] DEBUG - id: 2  
  6. 2013-01-05 17:25:34 642 [5692] DEBUG - count: 3  
  7. 2013-01-05 17:25:34 646 [5692] DEBUG - id: 3  
  8. 2013-01-05 17:25:34 649 [5692] DEBUG - count: 4  
test_ioserivice的执行结果:
[cpp]  view plain copy print ?
  1. 2013-01-05 17:26:28 071 [3236] DEBUG - id: 1  
  2. 2013-01-05 17:26:28 071 [5768] DEBUG - id: 2  
  3. 2013-01-05 17:26:28 071 [5108] DEBUG - id: 3  
  4. 2013-01-05 17:26:28 076 [3236] DEBUG - count: 1  
  5. 2013-01-05 17:26:28 079 [5768] DEBUG - count: 2  
  6. 2013-01-05 17:26:28 083 [5108] DEBUG - count: 3  
  7. 2013-01-05 17:26:28 087 [3236] DEBUG - id: 4  
  8. 2013-01-05 17:26:28 099 [3236] DEBUG - count: 4  
从结果可以看到, 在test_strand中print中两个打印函数成对执行, 在test_ioservice两个打印函数就没有线程安全可言了.
如果要保证test_ioservice同步, 就要加上mutex, 在代码中被注释的那句. 

注意从日志的线程号中可知: 真正执行print()是主线程, ios1, ios2, 而t1, t2, t3, t4线程只是往ioservice的队列中加入任务.

这篇关于【Boost】boost库asio详解1——strand与io_service区别的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1062115

相关文章

SpringIoC与SpringDI详解

《SpringIoC与SpringDI详解》本文介绍了Spring框架中的IoC(控制反转)和DI(依赖注入)概念,以及如何在Spring中使用这些概念来管理对象和依赖关系,感兴趣的朋友一起看看吧... 目录一、IoC与DI1.1 IoC1.2 DI二、IoC与DI的使用三、IoC详解3.1 Bean的存储

Spring Cloud之注册中心Nacos的使用详解

《SpringCloud之注册中心Nacos的使用详解》本文介绍SpringCloudAlibaba中的Nacos组件,对比了Nacos与Eureka的区别,展示了如何在项目中引入SpringClo... 目录Naacos服务注册/服务发现引⼊Spring Cloud Alibaba依赖引入Naco编程s依

C语言中的浮点数存储详解

《C语言中的浮点数存储详解》:本文主要介绍C语言中的浮点数存储详解,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、首先明确一个概念2、接下来,讲解C语言中浮点型数存储的规则2.1、可以将上述公式分为两部分来看2.2、问:十进制小数0.5该如何存储?2.3 浮点

Java逻辑运算符之&&、|| 与&、 |的区别及应用

《Java逻辑运算符之&&、||与&、|的区别及应用》:本文主要介绍Java逻辑运算符之&&、||与&、|的区别及应用的相关资料,分别是&&、||与&、|,并探讨了它们在不同应用场景中... 目录前言一、基本概念与运算符介绍二、短路与与非短路与:&& 与 & 的区别1. &&:短路与(AND)2. &:非短

大数据spark3.5安装部署之local模式详解

《大数据spark3.5安装部署之local模式详解》本文介绍了如何在本地模式下安装和配置Spark,并展示了如何使用SparkShell进行基本的数据处理操作,同时,还介绍了如何通过Spark-su... 目录下载上传解压配置jdk解压配置环境变量启动查看交互操作命令行提交应用spark,一个数据处理框架

MyBatis-Plus中Service接口的lambdaUpdate用法及实例分析

《MyBatis-Plus中Service接口的lambdaUpdate用法及实例分析》本文将详细讲解MyBatis-Plus中的lambdaUpdate用法,并提供丰富的案例来帮助读者更好地理解和应... 目录深入探索MyBATis-Plus中Service接口的lambdaUpdate用法及示例案例背景

MySQL中COALESCE函数示例详解

《MySQL中COALESCE函数示例详解》COALESCE是一个功能强大且常用的SQL函数,主要用来处理NULL值和实现灵活的值选择策略,能够使查询逻辑更清晰、简洁,:本文主要介绍MySQL中C... 目录语法示例1. 替换 NULL 值2. 用于字段默认值3. 多列优先级4. 结合聚合函数注意事项总结C

Java实现数据库图片上传功能详解

《Java实现数据库图片上传功能详解》这篇文章主要为大家详细介绍了如何使用Java实现数据库图片上传功能,包含从数据库拿图片传递前端渲染,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1、前言2、数据库搭建&nbsChina编程p; 3、后端实现将图片存储进数据库4、后端实现从数据库取出图片给前端5、前端拿到

Windows命令之tasklist命令用法详解(Windows查看进程)

《Windows命令之tasklist命令用法详解(Windows查看进程)》tasklist命令显示本地计算机或远程计算机上当前正在运行的进程列表,命令结合筛选器一起使用,可以按照我们的需求进行过滤... 目录命令帮助1、基本使用2、执行原理2.1、tasklist命令无法使用3、筛选器3.1、根据PID

MySql中的数据库连接池详解

《MySql中的数据库连接池详解》:本文主要介绍MySql中的数据库连接池方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录mysql数据库连接池1、概念2、为什么会出现数据库连接池3、原理4、数据库连接池的提供商5、DataSource数据源6、DBCP7、C