asio 中strand的作用
- 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的队列中加入任务.
asio 中strand的作用的更多相关文章
- (原创)拨开迷雾见月明-剖析asio中的proactor模式(二)
在上一篇博文中我们提到异步请求是从上层开始,一层一层转发到最下面的服务层的对象win_iocp_socket_service,由它将请求转发到操作系统(调用windows api),操作系统处理完异步 ...
- (原创)拨开迷雾见月明-剖析asio中的proactor模式(一)
使用asio之前要先对它的设计思想有所了解,了解设计思想将有助于我们理解和应用asio.asio是基于proactor模式的,asio的proactor模式隐藏于大量的细节当中,要找到它的踪迹,往往有 ...
- web.xml中load-on-startup的作用
如下一段配置,熟悉DWR的再熟悉不过了:<servlet> <servlet-name>dwr-invoker</servlet-name> <ser ...
- C#中构造函数的作用
C#中构造函数的作用 共同点: 都是实例化对象,初始化数据的 默认构造是说所有的类都从祖先object那继承了空参的构造方法,你不写与写空参构造都存在,而有参数的构造一般是自己写的,写就有不写就没有, ...
- MySQL数据库中delimiter的作用概述
以下的文章主要是向大家描述的是MySQL数据库中delimiter的作用是什么?我们一般都认为这个命令和存储过程关系不大,到底是不是这样的呢?以下的文章将会给你相关的知识,望你会有所收获. 其实就是告 ...
- js中getBoundingClientRect的作用及兼容方案
js中getBoundingClientRect的作用及兼容方案 1.getBoundingClientRect的作用 getBoundingClientRect用于获取某个html元素相对于视窗的位 ...
- Linq中关键字的作用及用法
Linq中关键字的作用及用法 1.All:确定序列中的所有元素是否都满足条件.如果源序列中的每个元素都通过指定谓词中的测试,或者序列为空,则为 true:否则为 false. Demo: 此示例使用 ...
- JAVA中protected的作用
JAVA中protected的作用 1.public:public表明该数据成员.成员函数是对所有用户开放的,所有用户都可以直接进行调用 2.private:private表示私有,私有的意思就是 ...
- url中#号的作用
url中#号的作用就是本页面位置跳转 比如这个url地址:http://www.aaaaa.com/index.html?ad=34&m=c#red red就是index.html页面的依哥位 ...
随机推荐
- odoo多币种
配置 启用多币种特性,并设置本位币 Gain exchange rate account 汇损收益科目,一般为财务费用下的二级科目 Loss exchange rate account 汇损损 ...
- Golang Map Addressability
http://wangzhezhe.github.io/blog/2016/01/22/golangmapaddressability-dot-md/ 在golang中关于map可达性的问题(addr ...
- Spring延迟加载
如下内容引用自:http://www.cnblogs.com/wcyBlog/p/3756624.html 1.Spring中lazy-init详解ApplicationContext实现的默认行为就 ...
- vim 模式切换
1. 从插入模式退回到normal模式 <esc> <C-c> <C-[>
- 运维基础-Linux发展史、安装、基本操作
Linux是目前互联网运维.大数据.云计算方向首选操作系统平台,能够在物理服务器Dell.hp.等server,以及当前主流的云平台,阿里云,腾讯云上面部署 发展史 . . .略过..... 物理服务 ...
- 项目中遇到Uncaught TypeError: Converting circular structure to JSON报错问题
最近公司项目中出现一个报错Uncaught TypeError: Converting circular structure to JSON,,根据上述报错可以知道代码是运行到JSON.stringi ...
- LeetCode(70)题解: climbing-stairs
https://leetcode.com/problems/climbing-stairs/ 题目: You are climbing a stair case. It takes n steps t ...
- crazyflie2.0 RCC时钟知识
因为眼下手里仅仅有16MHZ的2520封装的贴片晶振,8MHZ这样的封装做不到这么小,所以就先用16MHZ,这样我们就须要改动程序相关的RCC时钟: 1,stm32f4xx.h #define HSE ...
- EasyIPCamera实现Windows PC桌面、安卓Android桌面同屏直播,助力无纸化会议系统
最近在EasyDarwin开源群里,有不少用户私信需求,要做一种能够多端同屏的系统,细分下来有屏幕采集端和同屏端,屏幕采集端细想也就是一个低延时的流媒体音视频服务器,同屏端也就是一个低延时的播放器,负 ...
- EasyDarwin开源流媒体服务器高性能设计之无锁队列
本文来自EasyDarwin团队Fantasy(fantasy(at)easydarwin.org) 一. EasyDarwin任务队列实现 EasyDarwin的任务队列是通过OSQueue类来组织 ...