[cpp] view plain copy  print?
  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的执行结果:

[cpp] view plain copy  print?
  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的执行结果:

[cpp] view plain copy  print?
  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】boost库asio详解2——strand与io_service区别相关推荐

  1. 【Boost】boost库asio详解1——strand与io_service区别

    namespace {// strand提供串行执行, 能够保证线程安全, 同时被post或dispatch的方法, 不会被并发的执行. // io_service不能保证线程安全boost::asi ...

  2. 【Boost】boost库asio详解7——boost::asio::buffer用法

    1. asio::buffer常用的构造方法 asio::buffer有多种的构造方法,而且buffer大小是自动管理的 1.1 字符数组 [cpp] view plain copy  print? ...

  3. 【Boost】boost库asio详解8——TCP的简单例子1

    摘于boost官网的几个例子, 做了点小修改, 笔记之. 同步客户端 [cpp] view plain copy  print? void test_asio_synclient() { typede ...

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

    io_service::work类可以使io_service::run函数在没有任务的时候仍然不返回,直至work对象被销毁. [cpp] view plaincopy print? void tes ...

  5. 【Boost】boost库asio详解9——UDP的简单例子1

    服务器: #include "stdafx.h" #include <iostream> #include <boost/asio.hpp> #includ ...

  6. 【Boost】boost库asio详解9——TCP的简单例子2

    客户端: // Client.cpp : 定义控制台应用程序的入口点. //#include "stdafx.h" #include <iostream> #inclu ...

  7. 【Boost】boost库asio详解6——boost::asio::error的用法浅析

    1. 概述 一般而言我们创建用于接收error的类型大多声明如下: [cpp] view plain copy  print? boost::system::error_code error 我们用这 ...

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

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

  9. 【Boost】boost库asio详解4——deadline_timer使用说明

    deadline_timer和socket一样,都用io_service作为构造函数的参数.也即,在其上进行异步操作,都将导致和io_service所包含的iocp相关联.这同样意味着在析构 io_s ...

最新文章

  1. linux centos 丢失 grub.conf 启动系统
  2. conv2d函数_Pytorch 从0开始学(6)——Conv2d 详解
  3. Dockerfile项目环境介绍
  4. 获取族_批量添加族参数(上)
  5. Google 的开源技术protobuf 简介与例子
  6. Qt工作笔记-重写滚轮事件,实现界面的增加、减少(放大、缩小)
  7. 为什么优酷站点限制不了_什么是站点可靠性工程师,为什么要考虑这个职业道路
  8. 【codevs1226】倒水问题,BFS练习
  9. NodeJS服务器退出:完成任务,优雅退出
  10. android游戏勿扰,App+1 | Android 勿扰自动化,看剧、游戏更「沉浸」:NoPopping
  11. ARP欺骗-教程详解
  12. netperf 学习笔记
  13. 车联网信息服务数据——采集合规性——行业标准解读
  14. 盘点国外知名量化基金
  15. UISlider实现背景图
  16. PTA-IP地址转换
  17. 教你如何用python制作平面直角坐标系模拟器 python项目小发明 【安安教具】-【数学】-【平面直角坐标系】模拟器
  18. 人物画像————圆球转动效果
  19. 【FPGA知识点】八段共阳极数码管编码表
  20. 数据应用案例之“客户画像体系”

热门文章

  1. 默认标准错误文件linux,Linux中标准输出和标准错误的重导向
  2. Java:ThreadPoolExecutor解析续--Executors
  3. 天津市职高高一计算机试题及答案,职高(中职)数学(基础模块)上册题库.doc
  4. android中调用fft函数,J使用PCM数据在Android中转换FFT(JTransforms FFT in Android from PCM data)...
  5. 解决 Tomcat 下 getInitParameter 返回 null
  6. CloudCare容器技术白皮书
  7. 苦酒入喉心作痛,红酒入鹅鹅想哭——震惊!勒索病毒想哭靠wine感染了Ubuntu16.04...
  8. Redis的数据类型之String
  9. MySQL之mysql客户端工作的批处理一些使用手法
  10. Mac下crontab -e没结果的解决办法