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

  • 相关阅读:
    字号、pt、px、em换算对照表
    回车自动提交 禁止回车自动提交
    working copy locked (svn)
    xUnit asp.net单元测试工具基本使用
    防御网站攻击 1
    Access restriction: The type HttpServlet is not accessible due to restriction on required library xxxx\servletapi.jar
    【转载】将sqlserver表中的数据导出sql语句或生成insert into语句
    动态切换数据源(spring+hibernate)
    MSSQL2005移植到MYSQL 5.0
    C++ Primer 4 CPP Note 2.1.1 整型和浮点型
  • 原文地址:https://www.cnblogs.com/lidabo/p/7449164.html
Copyright © 2020-2023  润新知