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等函数适配器,这些函数绑定器和函数适配器使用起来比较麻烦,需要根据是全局 ...
随机推荐
- 破解Veeam过程
1)运行Veeam_Backup_Setup.exe,但是不要继续下一步: 2)进入到%temp%\IXP000.TMP目录,例如windows xp sp3环境默认为C:\Documents and ...
- javascript构造函数+原形继承+作用域扩充
目前为止我认为这是最佳的声明对象的模式,将今天学到的东西写下 <script type="text/javascript"> function Constructor( ...
- 关于Oracle dmp文件导入随笔
进入博客园已经两年多了,每次想写点什么,都是给自己个各种借口,不了了之~今天就从Oracle数据库最长用的导入开始吧! 1.低版本的exp/imp可以连接到高版本(或同版本)的数据库服务器,比如:10 ...
- struts 标签引用出错
几句句话概括 1.检查 web.xml 出现错误自己改 配置后filter jsp-config 2.检查 tld 目录下的东西 是否缺少 3. 将包复制到web的lib目录下后 之后 b ...
- 在msvc中使用Boost.Spirit.X3
Preface “Examples of designs that meet most of the criteria for "goodness" (easy to unders ...
- MFC的初始化过程和消息映射技术
1.删除#include <windows.h>--win32中的-(使用win32工程编程mfc必须删除) 添加#include <afxwin.h> -- mfc中的- 2 ...
- shell中的if语句
语法格式 if command;then commands fi 其中的command包含如下: shell command 任何shell命令,如果shell命令返回0,代表true,否则,代表fa ...
- React java.lang.UnsatisfiedLinkError: dlopen failed: "/data/data/com.edaixi.activity/lib-main/libgnustl_shared.so" is 32-bit instead of 64-bit
E/AndroidRuntime: FATAL EXCEPTION: main Process: com.edaixi.activity, PID: 3659 at java.lang.Runtime ...
- JQuery中parents和closest的区别
jquery中查找上层元素一般都习惯了用parents方法,往往忽略了还有一个效率更高的closest方法,看下w3cschool的解释 过程不一样,closest是找到一个即停止,而parents将 ...
- php开启伪静态(2转)
打开apache的配置文件httpd.conf找到#LoadModule rewrite_module modules/mod_rewrite.so把前面#去掉.没有则添加,但必选独占一行,使apac ...