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. C++11下的线程池以及灵活的functional + bind + lamda

    利用boost的thread实现一个线程类,维护一个任务队列,以便可以承载非常灵活的调用.这个线程类可以方便的为后面的线程池打好基础.线程池还是动态均衡,没有什么别的.由于minGW 4.7 对 C+ ...

  2. IO中手机旋转事件的传递

    UIApplication -> delegate -> widnow -> rootViewController

  3. C# 超级简单的Telnet (TcpClient)客户端

    基于Sockets 没什么好说的,代码说明了所有 using System; using System.Collections.Generic; using System.Linq; using Sy ...

  4. (转)[老老实实学WCF] 第二篇 配置WCF

    在上一篇中,我们在一个控制台应用程序中编写了一个简单的WCF服务并承载了它.先回顾一下服务端的代码: using System; using System.Collections.Generic; u ...

  5. C#设置鼠标在控件上面时,改变光标形状

    //设置鼠标在控件上面时,改变光标形状 private void pictureBox_macroLogo_MouseHover(object sender, System.EventArgs e) ...

  6. Java中通过递归调用删除文件夹下所有文件

    摘自 : http://blog.sina.com.cn/s/blog_79333b2c0100xiu4.html import java.io.File; public class FileTest ...

  7. css之自动换行-设计师零张

    自动换行问题,正常字符的换行是比较合理的,而连续的数字和英文字符常常将容器撑大,挺让人头疼,下面介绍的是CSS如何实现换行的方法 对于div,p等块级元素 正常文字的换行(亚洲文字和非亚洲文字)元素拥 ...

  8. jquery中checkbox全选失效的解决方法

    这篇文章主要介绍了jquery中checkbox全选失效的解决方法,需要的朋友可以参考下     如果你使用jQuery 1.6 ,代码if ( $(elem).attr(“checked”) ),将 ...

  9. Java笔记--java一行一行写入或读取数据

    转自 Ruthless java一行一行写入或读取数据 链接:http://www.cnblogs.com/linjiqin/archive/2011/03/23/1992250.html 假如E:/ ...

  10. Codeforces 245H Queries for Number of Palindromes

    http://codeforces.com/contest/245/problem/H 题意:给定一个字符串,每次给个区间,求区间内有几个回文串(n<=5000) 思路:设定pd[i][j]代表 ...