【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

相关文章

MySQL 筛选条件放 ON后 vs 放 WHERE 后的区别解析

《MySQL筛选条件放ON后vs放WHERE后的区别解析》文章解释了在MySQL中,将筛选条件放在ON和WHERE中的区别,文章通过几个场景说明了ON和WHERE的区别,并总结了ON用于关... 今天我们来讲讲数据库筛选条件放 ON 后和放 WHERE 后的区别。ON 决定如何 "连接" 表,WHERE

Mybatis的mapper文件中#和$的区别示例解析

《Mybatis的mapper文件中#和$的区别示例解析》MyBatis的mapper文件中,#{}和${}是两种参数占位符,核心差异在于参数解析方式、SQL注入风险、适用场景,以下从底层原理、使用场... 目录MyBATis 中 mapper 文件里 #{} 与 ${} 的核心区别一、核心区别对比表二、底

Python容器转换与共有函数举例详解

《Python容器转换与共有函数举例详解》Python容器是Python编程语言中非常基础且重要的概念,它们提供了数据的存储和组织方式,下面:本文主要介绍Python容器转换与共有函数的相关资料,... 目录python容器转换与共有函数详解一、容器类型概览二、容器类型转换1. 基本容器转换2. 高级转换示

HTML5的input标签的`type`属性值详解和代码示例

《HTML5的input标签的`type`属性值详解和代码示例》HTML5的`input`标签提供了多种`type`属性值,用于创建不同类型的输入控件,满足用户输入的多样化需求,从文本输入、密码输入、... 目录一、引言二、文本类输入类型2.1 text2.2 password2.3 textarea(严格

C++ move 的作用详解及陷阱最佳实践

《C++move的作用详解及陷阱最佳实践》文章详细介绍了C++中的`std::move`函数的作用,包括为什么需要它、它的本质、典型使用场景、以及一些常见陷阱和最佳实践,感兴趣的朋友跟随小编一起看... 目录C++ move 的作用详解一、一句话总结二、为什么需要 move?C++98/03 的痛点⚡C++

MySQL中between and的基本用法、范围查询示例详解

《MySQL中betweenand的基本用法、范围查询示例详解》BETWEENAND操作符在MySQL中用于选择在两个值之间的数据,包括边界值,它支持数值和日期类型,示例展示了如何使用BETWEEN... 目录一、between and语法二、使用示例2.1、betwphpeen and数值查询2.2、be

python中的flask_sqlalchemy的使用及示例详解

《python中的flask_sqlalchemy的使用及示例详解》文章主要介绍了在使用SQLAlchemy创建模型实例时,通过元类动态创建实例的方式,并说明了如何在实例化时执行__init__方法,... 目录@orm.reconstructorSQLAlchemy的回滚关联其他模型数据库基本操作将数据添

Java中ArrayList与顺序表示例详解

《Java中ArrayList与顺序表示例详解》顺序表是在计算机内存中以数组的形式保存的线性表,是指用一组地址连续的存储单元依次存储数据元素的线性结构,:本文主要介绍Java中ArrayList与... 目录前言一、Java集合框架核心接口与分类ArrayList二、顺序表数据结构中的顺序表三、常用代码手动

Spring Boot Interceptor的原理、配置、顺序控制及与Filter的关键区别对比分析

《SpringBootInterceptor的原理、配置、顺序控制及与Filter的关键区别对比分析》本文主要介绍了SpringBoot中的拦截器(Interceptor)及其与过滤器(Filt... 目录前言一、核心功能二、拦截器的实现2.1 定义自定义拦截器2.2 注册拦截器三、多拦截器的执行顺序四、过

JAVA线程的周期及调度机制详解

《JAVA线程的周期及调度机制详解》Java线程的生命周期包括NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING和TERMINATED,线程调度依赖操作系统,采用抢占... 目录Java线程的生命周期线程状态转换示例代码JAVA线程调度机制优先级设置示例注意事项JAVA线程