• asio 中strand的作用


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

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

  • 相关阅读:
    【java多线程】队列系统之说说队列Queue
    【传输协议】什么是CA证书
    5.1 javassist基本使用
    第四章 dubbo内核之aop源码解析
    第三章 dubbo内核之ioc源码解析
    2.2 dubbo-spi源码解析
    2.1 jdk-spi的实现原理
    第一章 第一个dubbo项目
    第零章 dubbo源码解析目录
    macOS Sierra10.12.5 显示允许任何来源
  • 原文地址:https://www.cnblogs.com/lidabo/p/7449164.html
Copyright © 2020-2023  润新知