在几个线程上运行asio strand和io_service

时间:2013-12-04 09:45:49

标签: c++ multithreading asynchronous boost-asio

我不确定与股线有关的一个细节。

假设以下情况:两个独立的对象,每个对象都有自己的链。并且每个链与一个共同的io_service相关。每个对象都使用他的strand来发布和包装异步操作。如果我在多个线程上有这个(唯一的)io_service .run(),我不确定是否会发生以下情况:

  1. 其中一个对象发布的所有操作和异步包装非并发。因此,与其中一个对象相关的所有操作都将按顺序执行(已发布的操作将按照与发布时相同的顺序执行。包装的异步操作将以未指定的顺序执行,因为它们是异步的,但仍然是串行执行的。)< / p>

  2. 源于不同对象的两个操作(因此从与同一个io_service相关的不同strand对象发布或包装)可以同时执行

  3. 总之,每个对象将按顺序执行其发布和包装的处理程序,但是从不同对象(子线)发布和包装的处理程序将同时执行。

       +-----------------+  +-----------------+
       | Obj1            |  | Obj2            |
       | +-------------+ |  | +-------------+ |             
       | |   Strand_1  | |  | |   Strand_2  | |               
       | +-------------+ |  | +-------------+ |                
       +--------+--------+  +-------+---------+                
                |                   |                          
                +--------+  +-------+                          
                         |  |                                         
                    +----+--+----+                                      
                    | io_service |                                      
                    +------------+                                      
                           |                                          
                           |                                          
                  +--------+-------+                         
                  |                |                                
             Thread1             Thread_2  
             io_service.run()    io_service.run()                              
    
  4. 我是对的吗?

    谢谢

2 个答案:

答案 0 :(得分:7)

简而言之,strand保证对其自己的处理程序进行顺序调用,但不保证从不同的链中并发执行处理程序。因此,这些要点的答案是:

  1. 是。顺序调用是有保证的。
  2. 是。并发执行可以发生,但无法保证。
  3. 是顺序调用,但是不保证并发执行

  4. strand维护自己的处理程序队列,并保证只有一个处理程序在io_service中,导致处理程序在被放入io_service之前被同步。因此,通过strand发布或发送的所有处理程序将按顺序执行。

    可能会发生通过不同strand发布或分派的处理程序的并发执行,但不能保证会发生。 documentation州:

      

    该实现不保证将同时调用通过不同strand对象发布或分派的处理程序。

    因此,如果Thread1正在执行通过Strand_1发布的处理程序,Boost.Asio将不会使用该信息来保证通过Strand_2发布的处理程序将由Thread2执行;但是,有可能选择Thread2根据其他实现细节从Strand_2执行处理程序,例如作为运行io_service的线程列表中的下一个可用线程。 / p>

    例如,考虑3个处理程序ABC已准备好在io_service内运行的情况:

    • A张贴于Strand_1
    • B未通过strand发布。
    • C是通过Strand_2发布的。

    如果Thread1Thread2正在运行io_service,那么一个可能的执行顺序是:

    Thread1         | Thread2
    ----------------+----------------
    start A()       | start B()
    `-- finish A()  | |
    start C()       | `-- finish B()
    `-- finish C()  |
    

    图示的执行顺序显示不能保证通过不同的A s(Cstrand分别发布的处理程序(Strand_1Strand_2)同时执行。

答案 1 :(得分:1)

  

其中一个对象发布的所有操作和异步包装将同时执行。因此,与其中一个对象相关的所有操作都将按顺序执行(已发布的操作将按照与发布时相同的顺序执行。包装的异步操作将以未指定的顺序执行,因为它们是异步的,但仍然是串行执行的。)< / p>

  

可以同时执行两个来自不同对象的操作(因此从与同一个io_service相关的不同strand对象发布或包装)。

  

总之,每个对象将按顺序执行他的已发布和已包装的处理程序,但是从不同对象(子线)发布和包装的处理程序将同时执行。