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页面的依哥位 ...
随机推荐
- vue 避免渲染时闪烁
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8&quo ...
- 工作总结 mvc 调页面传参数 参数值会一直保存 在这个页面上的
意思是 两个页面均可以 获取到id 和 goodsType 都可以获取 id goodsType post 的 还多带点属性值 form data 页面上带过去的 (新增 编辑)
- 【CODEFORCES】 B. Dreamoon and Sets
B. Dreamoon and Sets time limit per test 1 second memory limit per test 256 megabytes input standard ...
- RFID 卡片防复制
RFID 卡片防复制 这里的卡指的 MIFARE Classic 系列 或 NTAG 系列的卡.其它的卡没接触过,不了解. 防伪有两层意义: 卡片防复制.比如小区卡被复制,使得出入小区的人员管理更困难 ...
- MFC学习之Radio---MFC Radio按钮组的使用例子
首先我们要完成一个功能,在一个添加新用户的场景里,通过Radio按钮来判断用户选择的是管理员还是普通用户. 要使用Radio组的功能首先我们必须作如下设置: 1.2个Radio按钮的ID号不同,但是他 ...
- gcc參数总结
/*gcc 命令总结*/ 补充下gcc的知识,免得被大自然说编译原理不行.. 1.-o 參数 參数说明: -o參数用来指定生成程序的名字 gcc test.c 会编译出一个名为a.out的程序 gcc ...
- 记使用WaitGroup时的一个错误
记使用WaitGroup时的一个错误 近期重构我之前写的server代码时,不当使用了WaitGroup,碰到了个错误,记录下. package main import ( "fmt&quo ...
- web前端页面中异步使用百度地图API
<div id="allmap"></div> //百度地图API功能 function loadJScript() { var script = docu ...
- 我读过的最好的epoll讲解
首先我们来定义流的概念,一个流可以是文件,socket,pipe等等可以进行I/O操作的内核对象. 不管是文件,还是套接字,还是管道,我们都可以把他们看作流. 之后我们来讨论I ...
- Hackerspace
Hackerspace Software - HackerspaceWiki https://wiki.hackerspaces.org/Hackerspace_Software Hackerspac ...