我目前正在尝试获取 boost::asio
股。这样做,我一直在阅读有关“调用 strand post/dispatch
inside or outside a strand”的内容。不知何故,我无法弄清楚 inside strand 与 through strand 有何不同,因此无法理解在 outside调用 strand 函数的概念em> 链。
可能我的拼图中只少了一小块。有人可以举例说明如何在链内或链外调用链吗?
到目前为止,我认为我所理解的是,通过 strand 发布一些内容是
m_strand.post(myfunctor);
或
m_strand.wrap(myfunctor);
io_svc.post(myfunctor);
后者是否被视为对 dispatch
的调用?在链外(而不是另一个调用 post
在它里面)?股线的“内部领域”与股线运行的线程之间是否存在某种关系?
如果在链中只是为了调用链的功能,那么 strand
class's documentation将毫无意义。它指出 strand::post
可以在链外调用......这正是我不明白的部分。
最佳答案
即使我在理解这个概念时遇到了一些困难,但在我开始处理 libdispatch
后就变得清晰了。它帮助我更好地使用 asio
映射事物。
现在让我们看看如何理解strand
。将 strand
视为需要执行的 handlers
串行队列。
现在,这些处理程序在哪里执行?在 worker
线程中。
这些工作线程是从哪里来的?从您在创建 strand 时传递的 io_service
对象。
像这样的东西:
asio::strand s(io_serv_obj);
现在,您一定知道,io_service::run
可以由单个线程或多个线程调用。在我们的例子中,调用 io_serv_obj
的 run
方法的线程是该链的工作线程。因此,它可以是单线程的,也可以是多线程的。
回到问题上来,当您发布
一个处理程序时,该处理程序总是在我们谈到的串行队列中排队。工作线程将一个接一个地从队列中获取处理程序。
现在,当您进行调度
时,asio 会为您做一些优化:
- 它检查您是从工作线程之一还是从其他线程(可能是其他
io_service
实例)调用它。当它在 strand 的当前执行上下文之外被调用时,就是在strand 之外
调用它的时候。因此,在outside
情况下,dispatch 只会在队列中有其他处理程序等待时像post
一样将处理程序入队,或者在可以保证它时直接调用它不会与当时可能在其中一个工作线程中运行的该队列中的任何其他处理程序同时调用。
更新:
如评论部分所述,inside
表示在另一个处理程序中调用
即例如:我发布了一个处理程序 A
并且在该处理程序中,我是执行另一个处理程序的 dispatch
。现在,正如 #2 中所解释的那样,如果在 strands 串行队列中没有其他处理程序在等待,则将同步调用调度处理程序。如果不满足此条件,则意味着 dispatch
从 outside
调用。
- 现在,如果您从链的
外部
调用dispatch
,即不在当前执行上下文中,asio 会检查其callstack
以查看是否其串行队列中存在的任何其他处理程序是否正在运行。如果不是,那么它将直接同步调用该处理程序。因此,将处理程序排队是没有成本的(我认为也不会进行额外的分配,但不确定)。
现在让我们看看文档链接:
s.dispatch(a) happens-before s.post(b), where the former is performed outside the strand
这意味着,如果 dispatch
是从当前 run
之外的某个地方调用的,或者有其他处理程序已经入队,那么它需要将处理程序入队,它只是不能同步调用它。由于它是一个串行队列,a
将在 b
之前执行。
是否有另一个调用 s.dispatch(c)
以及 a 和 b 但在 a
和 b
之前(按照上述顺序) 入队,那么 c
将在 a
和 b
之前执行,但绝不会在 b
之前执行一个
。
希望这能消除您的疑虑。
关于c++ - 链内是什么意思?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37831235/