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. void print(int id)
  9. {
  10. // boost::mutex::scoped_lock lock(m_mutex);
  11. static int count = 0;
  12. PRINT_DEBUG("id: " << boost::lexical_cast<std::string>(id));
  13. PRINT_DEBUG("count: " << boost::lexical_cast<std::string>(++count));
  14. }
  15. void ioRun1()
  16. {
  17. while(true)
  18. {
  19. m_service.run();
  20. }
  21. }
  22. void ioRun2()
  23. {
  24. while(true)
  25. {
  26. m_service.run();
  27. }
  28. }
  29. void strand_print1()
  30. {
  31. // PRINT_DEBUG("Enter print1");
  32. m_strand.dispatch(boost::bind(print, 1));
  33. // PRINT_DEBUG("Exit print1");
  34. }
  35. void strand_print2()
  36. {
  37. // PRINT_DEBUG("Enter print2");
  38. m_strand.post(boost::bind(print, 2));
  39. // PRINT_DEBUG("Exit print2");
  40. }
  41. void strand_print3()
  42. {
  43. // PRINT_DEBUG("Enter print3");
  44. m_strand.post(boost::bind(print, 3));
  45. // PRINT_DEBUG("Exit print3");
  46. }
  47. void strand_print4()
  48. {
  49. // PRINT_DEBUG("Enter print4");
  50. m_strand.post(boost::bind(print, 4));
  51. // PRINT_DEBUG("Exit print4");
  52. }
  53. // 将上面的m_strand换成m_service后,
  54. void service_print1()
  55. {
  56. // PRINT_DEBUG("Enter print1");
  57. m_service.dispatch(boost::bind(print, 1));
  58. // PRINT_DEBUG("Exit print1");
  59. }
  60. void service_print2()
  61. {
  62. // PRINT_DEBUG("Enter print2");
  63. m_service.post(boost::bind(print, 2));
  64. // PRINT_DEBUG("Exit print2");
  65. }
  66. void service_print3()
  67. {
  68. // PRINT_DEBUG("Enter print3");
  69. m_service.post(boost::bind(print, 3));
  70. // PRINT_DEBUG("Exit print3");
  71. }
  72. void service_print4()
  73. {
  74. // PRINT_DEBUG("Enter print4");
  75. m_service.post(boost::bind(print, 4));
  76. // PRINT_DEBUG("Exit print4");
  77. }
  78. }
  79. void test_strand()
  80. {
  81. boost::thread ios1(ioRun1);
  82. boost::thread ios2(ioRun2);
  83. boost::thread t1(strand_print1);
  84. boost::thread t2(strand_print2);
  85. boost::thread t3(strand_print3);
  86. boost::thread t4(strand_print4);
  87. t1.join();
  88. t2.join();
  89. t3.join();
  90. t4.join();
  91. m_server.run();
  92. }
  93. void test_service()
  94. {
  95. boost::thread ios1(ioRun1);
  96. boost::thread ios2(ioRun2);
  97. boost::thread t1(service_print1);
  98. boost::thread t2(service_print2);
  99. boost::thread t3(service_print3);
  100. boost::thread t4(service_print4);
  101. t1.join();
  102. t2.join();
  103. t3.join();
  104. t4.join();
  105. m_service.run();
  106. }

test_strand的执行结果:

  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的执行结果:

  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的队列中加入任务.

asio 中strand的作用的更多相关文章

  1. (原创)拨开迷雾见月明-剖析asio中的proactor模式(二)

    在上一篇博文中我们提到异步请求是从上层开始,一层一层转发到最下面的服务层的对象win_iocp_socket_service,由它将请求转发到操作系统(调用windows api),操作系统处理完异步 ...

  2. (原创)拨开迷雾见月明-剖析asio中的proactor模式(一)

    使用asio之前要先对它的设计思想有所了解,了解设计思想将有助于我们理解和应用asio.asio是基于proactor模式的,asio的proactor模式隐藏于大量的细节当中,要找到它的踪迹,往往有 ...

  3. web.xml中load-on-startup的作用

    如下一段配置,熟悉DWR的再熟悉不过了:<servlet>   <servlet-name>dwr-invoker</servlet-name>   <ser ...

  4. C#中构造函数的作用

    C#中构造函数的作用 共同点: 都是实例化对象,初始化数据的 默认构造是说所有的类都从祖先object那继承了空参的构造方法,你不写与写空参构造都存在,而有参数的构造一般是自己写的,写就有不写就没有, ...

  5. MySQL数据库中delimiter的作用概述

    以下的文章主要是向大家描述的是MySQL数据库中delimiter的作用是什么?我们一般都认为这个命令和存储过程关系不大,到底是不是这样的呢?以下的文章将会给你相关的知识,望你会有所收获. 其实就是告 ...

  6. js中getBoundingClientRect的作用及兼容方案

    js中getBoundingClientRect的作用及兼容方案 1.getBoundingClientRect的作用 getBoundingClientRect用于获取某个html元素相对于视窗的位 ...

  7. Linq中关键字的作用及用法

    Linq中关键字的作用及用法 1.All:确定序列中的所有元素是否都满足条件.如果源序列中的每个元素都通过指定谓词中的测试,或者序列为空,则为 true:否则为 false. Demo: 此示例使用 ...

  8. JAVA中protected的作用

    JAVA中protected的作用   1.public:public表明该数据成员.成员函数是对所有用户开放的,所有用户都可以直接进行调用 2.private:private表示私有,私有的意思就是 ...

  9. url中#号的作用

    url中#号的作用就是本页面位置跳转 比如这个url地址:http://www.aaaaa.com/index.html?ad=34&m=c#red red就是index.html页面的依哥位 ...

随机推荐

  1. Android记录24-WebView实现白天/夜间阅读模式

    前言 本篇博客给大家分享一个WebView的使用案例.实现Android调用JavaScript代码来控制白天/夜间模式. 关于WebView怎样使用,官网有非常好的说明,Building Web A ...

  2. Odoo webinar

    分享些 odoo9 webinar 视频     https://pan.baidu.com/s/1pLF5njt

  3. python(36)- 测试题

    1.8<<2等于? 32 “<<”位运算 264 132 64 32 16 8 4 2 1 原始位置 0 0 0 0 0 1 0 0 0 想左位移2位 0 0 0 1 0 0 ...

  4. shell(2):正则表达式

    一.整理正则表达式博客 (1)正则 正则就是用一些具有特殊含义的符号组合到一起(称为正则表达式)来描述字符或者字符串的方法.或者说:正则就是用来描述一类事物的规则. 在linux中,通配符是由shel ...

  5. 笔记08 WPF导航

    如何在winform中做导航,如何重定向界面,就产生了争执. 是用window还是Page还是UserControl? 先不管用啥.我们先比较一下各自的优缺点. 在WPF中使用导航,内容被组织在Pag ...

  6. shell grep正则匹配汉字

    Shell grep正则匹配中文 测试文本 demo_exe.c,内容如下,需要注意保存的编码格式,对输出到终端有影响: 我们中文操作系统ASNI默认是GBK的. #include<stdio. ...

  7. angular 复选框checkBox多选的应用

    应用场景是这样的,后台返回的数据在页面上复选框的形式repeat出来 可能会有两种需求: 第一:后台返回的只有项,而没有默认选中状态(全是待选状态) 这种情况相对简单只要repeat出相应选项 第二: ...

  8. 【机器学习算法-python实现】PCA 主成分分析、降维

    1.背景         PCA(Principal Component Analysis),PAC的作用主要是减少数据集的维度,然后挑选出基本的特征.         PCA的主要思想是移动坐标轴, ...

  9. js json按key值排序

    最近有个需求需要把json按key值进行排序,可是js并没有直接的函数可以对json进行排序的这么办呢? 然后想到了一个间接的方法来实现: 1.将json中的key值取出,存在一个数组中,然后对这个数 ...

  10. 怎样高速编译mediatek\operator以下代码

    mediatek\operator以下有单独的apk.也有overlay的数据,单独的apk会配置anroid.mk,找到相应的路径直接build. 假设是overlay,则编译原来应用的路径,比如 ...