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

boost库asio详解1——strand与io_service区别的更多相关文章

  1. boost库asio详解8——几个TCP的简单例子

    摘于boost官网的几个例子, 做了点小修改, 笔记之. 同步客户端 void test_asio_synclient() { typedef boost::asio::io_service IoSe ...

  2. 【Boost】boost库asio详解5——resolver与endpoint使用说明

    tcp::resolver一般和tcp::resolver::query结合用,通过query这个词顾名思义就知道它是用来查询socket的相应信息,一般而言我们关心socket的东东有address ...

  3. 【Boost】boost库asio详解3——io_service作为work pool

    无论如何使用,都能感觉到使用boost.asio实现服务器,不仅是一件非常轻松的事,而且代码很漂亮,逻辑也相当清晰,这点上很不同于ACE.使用io_service作为处理工作的work pool,可以 ...

  4. 【Boost】boost库asio详解2——io_service::run函数无任务时退出的问题

    io_service::work类可以使io_service::run函数在没有任务的时候仍然不返回,直至work对象被销毁. void test_asio_nowork() { boost::asi ...

  5. Python爬虫之selenium库使用详解

    Python爬虫之selenium库使用详解 本章内容如下: 什么是Selenium selenium基本使用 声明浏览器对象 访问页面 查找元素 多个元素查找 元素交互操作 交互动作 执行JavaS ...

  6. STC8H开发(二): 在Linux VSCode中配置和使用FwLib_STC8封装库(图文详解)

    目录 STC8H开发(一): 在Keil5中配置和使用FwLib_STC8封装库(图文详解) STC8H开发(二): 在Linux VSCode中配置和使用FwLib_STC8封装库(图文详解) 前面 ...

  7. 详解CALayer 和 UIView的区别和联系

    详解CALayer 和 UIView的区别和联系   前言 前面发了一篇iOS 面试的文章,在说到 UIView 和 CALayer 的区别和联系的时候,被喵神指出没有切中要点,所以这里就 CALay ...

  8. 详解path和classpath的区别

    详解path和classpath的区别 path的作用 path是系统用来指定可执行文件的完整路径,即使不在path中设置JDK的路径也可执行JAVA文件,但必须把完整的路径写出来,如C:\Progr ...

  9. Boost::bind使用详解

    1.Boost::bind 在STL中,我们经常需要使用bind1st,bind2st函数绑定器和fun_ptr,mem_fun等函数适配器,这些函数绑定器和函数适配器使用起来比较麻烦,需要根据是全局 ...

随机推荐

  1. WPF XAML之bing使用StringFormat(转)

    释义 BindingBase.StringFormat 属性 获取或设置一个字符串,该字符串指定如果绑定值显示为字符串,应如何设置该绑定的格式.        命名空间: System.Windows ...

  2. 轻量级的中文分词工具包 - IK Analyzer

    IK Analyzer是一个开源的,基于java语言开发的轻量级的中文分词工具包.从2006年12月推出1.0版开始, IKAnalyzer已经推出了4个大版本.最初,它是以开源项目Luence为应用 ...

  3. JVM的内存区域划分划分及作用

  4. deflate树与deflate编码

    关于deflate树,能搜到的资料非常少,这个概念来自gzip的压缩算法,是由huffman树转变过来的.这里简单记录下deflate树的生成过程以及deflate编码. 假设以5 8 9 10 14 ...

  5. shell中的case表达式

    语法格式 case var in pattern1 | patter2) command1 command2;; pattern3) command1 command2;; *) default co ...

  6. JS中的== 、===的用法和区别。

    JS中的== .===的用法和区别.[转] == 和 != 比较若类型不同,先偿试转换类型,再作值比较,最后返回值比较结果 . 而  === 和 !== 只有在相同类型下,才会比较其值 ======= ...

  7. Android开源库

    http://blog.csdn.net/xiaanming/article/details/9470223 一.兼容类库 ActionBarSherlock : Action Bar是Android ...

  8. JVM性能调优博客

    http://houjixin.blog.163.com/blog/static/35628410201411275719843/ http://blog.csdn.net/lastsweetop/a ...

  9. BZOJ 3550 Vacation

    http://www.lydsy.com/JudgeOnline/problem.php?id=3550 题意:有3N个数,你需要选出一些数,首先保证任意长度为N的区间中选出的数的个数<=K个, ...

  10. BZOJ 1063 道路设计NOI2008

    http://www.lydsy.com/JudgeOnline/problem.php?id=1063 题意:给你一棵树,也有可能是不连通的,把树分成几个链,求每个点到根经过的最大链数最小,而且要输 ...