c++ - 提升在多个线程上运行的 asio strand 和 io_service

标签 c++ multithreading asynchronous boost-asio

我不确定与 strands 相关的一个细节。

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

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

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

  3. 总而言之,每个对象将串行执行其发布和包装的处理程序,但来自不同对象(链)的发布和包装的处理程序将同时执行。

       +-----------------+  +-----------------+
       | Obj1            |  | Obj2            |
       | +-------------+ |  | +-------------+ |             
       | |   Strand_1  | |  | |   Strand_2  | |               
       | +-------------+ |  | +-------------+ |                
       +--------+--------+  +-------+---------+                
                |                   |                          
                +--------+  +-------+                          
                         |  |                                         
                    +----+--+----+                                      
                    | io_service |                                      
                    +------------+                                      
                           |                                          
                           |                                          
                  +--------+-------+                         
                  |                |                                
             Thread1             Thread_2  
             io_service.run()    io_service.run()                              
    

我说得对吗?

谢谢

最佳答案

简而言之,strand 保证顺序调用它自己的处理程序,但不保证来自不同 strand 的处理程序的并发执行。因此,这些问题的答案是:

  1. 是的。保证顺序调用。
  2. 是的。并发执行可能发生,但不能保证。
  3. 对顺序调用是肯定的,但对并发执行的保证不是。

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

通过不同的 strand 发布或分派(dispatch)的处理程序可能会并发执行,只是不能保证会发生。 documentation状态:

The implementation makes no guarantee that handlers posted or dispatched through different strand objects will be invoked concurrently.

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

例如,考虑 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()  |

图示的执行顺序表明处理程序(AC)通过不同的 strand(Strand_1)发布> 和 Strand_2 分别)不能保证同时执行。

关于c++ - 提升在多个线程上运行的 asio strand 和 io_service,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20371895/

相关文章:

Spring @Async 生成 LazyInitializationExceptions

c++ - 被隐式删除,因为默认定义的格式不正确 :

c++ - 无法连接QT信号

java - 程序终止时如何关闭端口?

java - Swing 应用程序中音频线程的设计模式 : How to notify midi executor is shutdown to drive a GUI state-change?

android - 在处理程序中创建警报对话框

c++ - 当不存在可选子字符串时,避免匹配中的空元素

c++ - ROS RVIZ : How to visualize a point cloud that doesn't have a fixed frame transform

c# - Task 和 Context 上的多个操作

JavaScript 似乎以错误的顺序执行代码