boost库asio详解1——strand与io_service区别
- namespace
- {
- // strand提供串行执行, 能够保证线程安全, 同时被post或dispatch的方法, 不会被并发的执行.
- // io_service不能保证线程安全
- boost::asio::io_service m_service;
- boost::asio::strand m_strand(m_service);
- boost::mutex m_mutex;
- void print(int id)
- {
- // boost::mutex::scoped_lock lock(m_mutex);
- static int count = 0;
- PRINT_DEBUG("id: " << boost::lexical_cast<std::string>(id));
- PRINT_DEBUG("count: " << boost::lexical_cast<std::string>(++count));
- }
- void ioRun1()
- {
- while(true)
- {
- m_service.run();
- }
- }
- void ioRun2()
- {
- while(true)
- {
- m_service.run();
- }
- }
- void strand_print1()
- {
- // PRINT_DEBUG("Enter print1");
- m_strand.dispatch(boost::bind(print, 1));
- // PRINT_DEBUG("Exit print1");
- }
- void strand_print2()
- {
- // PRINT_DEBUG("Enter print2");
- m_strand.post(boost::bind(print, 2));
- // PRINT_DEBUG("Exit print2");
- }
- void strand_print3()
- {
- // PRINT_DEBUG("Enter print3");
- m_strand.post(boost::bind(print, 3));
- // PRINT_DEBUG("Exit print3");
- }
- void strand_print4()
- {
- // PRINT_DEBUG("Enter print4");
- m_strand.post(boost::bind(print, 4));
- // PRINT_DEBUG("Exit print4");
- }
- // 将上面的m_strand换成m_service后,
- void service_print1()
- {
- // PRINT_DEBUG("Enter print1");
- m_service.dispatch(boost::bind(print, 1));
- // PRINT_DEBUG("Exit print1");
- }
- void service_print2()
- {
- // PRINT_DEBUG("Enter print2");
- m_service.post(boost::bind(print, 2));
- // PRINT_DEBUG("Exit print2");
- }
- void service_print3()
- {
- // PRINT_DEBUG("Enter print3");
- m_service.post(boost::bind(print, 3));
- // PRINT_DEBUG("Exit print3");
- }
- void service_print4()
- {
- // PRINT_DEBUG("Enter print4");
- m_service.post(boost::bind(print, 4));
- // PRINT_DEBUG("Exit print4");
- }
- }
- void test_strand()
- {
- boost::thread ios1(ioRun1);
- boost::thread ios2(ioRun2);
- boost::thread t1(strand_print1);
- boost::thread t2(strand_print2);
- boost::thread t3(strand_print3);
- boost::thread t4(strand_print4);
- t1.join();
- t2.join();
- t3.join();
- t4.join();
- m_server.run();
- }
- void test_service()
- {
- boost::thread ios1(ioRun1);
- boost::thread ios2(ioRun2);
- boost::thread t1(service_print1);
- boost::thread t2(service_print2);
- boost::thread t3(service_print3);
- boost::thread t4(service_print4);
- t1.join();
- t2.join();
- t3.join();
- t4.join();
- m_service.run();
- }
test_strand的执行结果:
- 2013-01-05 17:25:34 626 [8228] DEBUG - id: 4
- 2013-01-05 17:25:34 631 [8228] DEBUG - count: 1
- 2013-01-05 17:25:34 634 [5692] DEBUG - id: 1
- 2013-01-05 17:25:34 637 [5692] DEBUG - count: 2
- 2013-01-05 17:25:34 640 [5692] DEBUG - id: 2
- 2013-01-05 17:25:34 642 [5692] DEBUG - count: 3
- 2013-01-05 17:25:34 646 [5692] DEBUG - id: 3
- 2013-01-05 17:25:34 649 [5692] DEBUG - count: 4
test_ioserivice的执行结果:
- 2013-01-05 17:26:28 071 [3236] DEBUG - id: 1
- 2013-01-05 17:26:28 071 [5768] DEBUG - id: 2
- 2013-01-05 17:26:28 071 [5108] DEBUG - id: 3
- 2013-01-05 17:26:28 076 [3236] DEBUG - count: 1
- 2013-01-05 17:26:28 079 [5768] DEBUG - count: 2
- 2013-01-05 17:26:28 083 [5108] DEBUG - count: 3
- 2013-01-05 17:26:28 087 [3236] DEBUG - id: 4
- 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库asio详解1——strand与io_service区别的更多相关文章
- boost库asio详解8——几个TCP的简单例子
摘于boost官网的几个例子, 做了点小修改, 笔记之. 同步客户端 void test_asio_synclient() { typedef boost::asio::io_service IoSe ...
- 【Boost】boost库asio详解5——resolver与endpoint使用说明
tcp::resolver一般和tcp::resolver::query结合用,通过query这个词顾名思义就知道它是用来查询socket的相应信息,一般而言我们关心socket的东东有address ...
- 【Boost】boost库asio详解3——io_service作为work pool
无论如何使用,都能感觉到使用boost.asio实现服务器,不仅是一件非常轻松的事,而且代码很漂亮,逻辑也相当清晰,这点上很不同于ACE.使用io_service作为处理工作的work pool,可以 ...
- 【Boost】boost库asio详解2——io_service::run函数无任务时退出的问题
io_service::work类可以使io_service::run函数在没有任务的时候仍然不返回,直至work对象被销毁. void test_asio_nowork() { boost::asi ...
- Python爬虫之selenium库使用详解
Python爬虫之selenium库使用详解 本章内容如下: 什么是Selenium selenium基本使用 声明浏览器对象 访问页面 查找元素 多个元素查找 元素交互操作 交互动作 执行JavaS ...
- STC8H开发(二): 在Linux VSCode中配置和使用FwLib_STC8封装库(图文详解)
目录 STC8H开发(一): 在Keil5中配置和使用FwLib_STC8封装库(图文详解) STC8H开发(二): 在Linux VSCode中配置和使用FwLib_STC8封装库(图文详解) 前面 ...
- 详解CALayer 和 UIView的区别和联系
详解CALayer 和 UIView的区别和联系 前言 前面发了一篇iOS 面试的文章,在说到 UIView 和 CALayer 的区别和联系的时候,被喵神指出没有切中要点,所以这里就 CALay ...
- 详解path和classpath的区别
详解path和classpath的区别 path的作用 path是系统用来指定可执行文件的完整路径,即使不在path中设置JDK的路径也可执行JAVA文件,但必须把完整的路径写出来,如C:\Progr ...
- Boost::bind使用详解
1.Boost::bind 在STL中,我们经常需要使用bind1st,bind2st函数绑定器和fun_ptr,mem_fun等函数适配器,这些函数绑定器和函数适配器使用起来比较麻烦,需要根据是全局 ...
随机推荐
- (转)怎样查看局域网中自己的IP地址和其他电脑的IP地址?
开始菜单->运行->打cmd,回车->再弹出的黑框里打ipconfig -all,回车显示的IP Address就是你的ip地址看局域网的电脑的ip用软件比较方便,比如p2p终结者, ...
- redis的5种数据结构的简介
5种数据结构 1.字符串 Redis 字符串是一个字节序列.在 Redis 中字符串是二进制安全的,这意味着它们没有任何特殊终端字符来确定长度,所以可以存储任何长度为 512 兆的字符串. 示例 12 ...
- mysql配置文件转载
#BEGIN CONFIG INFO#DESCR: 4GB RAM, 只使用InnoDB, ACID, 少量的连接, 队列负载大#TYPE: SYSTEM#END CONFIG INFO ## 此my ...
- RadGrid SelectedIndexChanged 事件没反应的解决方法
Hello Hrushikesh, You can set ClientSettings.EnablePostBackOnRowClick to true along with ClientSetti ...
- NPOI导入导出Excel (2)
简单演示一下创建一个Workbook对象,添加一个工作表,在工作表中添加一行一列: using System;using System.Collections.Generic;using System ...
- tomcat重启或关闭后,上传文件消失 .
tomcat重启或关闭后,上传文件消失的问题,是因为在断电前myeclipse是启动的,断电时造成myeclipse异常关闭,再重新启动myeclipse时会重新发布项目,把先前发布的项目给覆盖了,所 ...
- js页面加载进度条(这个就比较正式了,改改时间就完事儿)
不废话,直接上代码 思路不难,就是一个animate方法配合随机数 duration内个三秒钟,是自定义的,可以改成页面加载时间,这样就完美了 <!doctype html> <ht ...
- mongodb3 权限认证问题总结
mongodb3 权限认证问题总结 标签(空格分隔): mongodb 权限 数据库 认证 ubuntu用户安装最新版本mongodb 添加key sudo apt-key adv --keyserv ...
- (转)centos6起/etc/syslog.conf不再有!而是/etc/rsyslog.conf代替!
centos6起/etc/syslog.conf不再有!而是/etc/rsyslog.conf代替!
- Keil C51程序设计中几种精确延时方法
1 使用定时器/计数器实现精确延时 单片机系统一般常选用11.059 2 MHz.12 MHz或6 MHz晶振.第一种更容易产生各种标准的波特率,后两种的一个机器周期分别为1 μs和2 μs,便于精确 ...