股内是什么意思

What does inside a strand mean?

本文关键字:意思 是什么      更新时间:2023-10-16

我目前正在尝试获得boost::asio股。这样做,我一直在阅读有关"在链调用链post/dispatch"的信息。不知何故,我无法弄清楚链内部与通过链有何不同,因此根本无法理解在链调用链函数的概念。

可能我的拼图中只少了一小块。有人可以举个例子,对链的调用如何在它的内部或外部?

到目前为止,我想我已经理解的是,通过一条线发布一些东西将是

m_strand.post(myfunctor);

m_strand.wrap(myfunctor);
io_svc.post(myfunctor); 

后者是否被认为是对链外dispatch的调用(而不是另一个是对链内post的调用)?链的"内部领域"和链操作的线之间是否存在某种关系?

如果位于链内只是为了调用链的功能,那么strand类的文档将毫无意义。它指出strand::post可以在链之外调用......这正是我不明白的部分。

甚至我在理解这个概念时也遇到了一些麻烦,但一旦我开始研究libdispatch,我就变得清晰起来了。它帮助我更好地绘制了asio

现在让我们看看如何从strand中理解一些意义。strand视为需要执行的handlers的串行队列。

现在,这些处理程序在哪里执行?在worker线程中。

这些工作线程从何而来?从创建链时传递io_service对象。 像这样:

asio::strand s(io_serv_obj);

现在,正如您必须知道的那样,io_service::run可以由单个线程或多个线程调用。在我们的例子中,调用io_serv_objrun方法的线程是该链的工作线程。因此,它可以是单线程的,也可以是多线程的。

回到链上,当你post处理程序时,该处理程序总是在我们讨论的串行队列中排队。工作线程将一个接一个地从队列中选取处理程序。

现在,当你做一个dispatch,asio会为你做一些优化:

  1. 检查您是从其中一个工作线程内部还是从某个其他线程(可能是其他某个io_service实例)调用它。当它在链的当前执行上下文之外被调用时,那就是它被称为outside the strand的时候。因此,在outside情况下,调度将像post一样将处理程序排队,当队列中有其他处理程序在等待时,调度将直接调用它,当它可以保证它不会与该队列中当时可能在其中一个工作线程中运行的任何其他处理程序同时调用时。

更新:如评论部分所述,inside意味着called within another handler,即例如:我A发布了一个处理程序,在该处理程序中,我正在对另一个处理程序进行dispatch。现在,正如 #2 中所解释的,如果链串行队列中没有其他处理程序在等待,则将同步调用调度处理程序。如果不满足此条件,则意味着从outside调用dispatch

  1. 现在,如果您从链outside调用dispatch,即不在当前执行上下文中,asio 会检查其callstack以查看其串行队列中存在的任何其他处理程序是否正在运行。如果没有,那么它将直接同步调用该处理程序。因此,对处理程序进行排队没有成本(我认为也不会进行额外的分配,但不确定)。

现在让我们看看文档链接:

s.dispatch(a) 发生在 s.post(b) 之前,其中执行前者 股外

这意味着,如果dispatch是从当前run之外的某个调用的,或者有其他处理程序已经排队,那么它需要对处理程序进行排队,只是无法同步调用它。由于它是一个串行队列,因此a将在b之前执行。

如果在 a 和 b 旁边有另一个调用s.dispatch(c)但在ab(按上述顺序)排队之前,那么c将在ab之前执行,但b绝不能在a之前执行。

希望这能消除您的疑虑。

对于给定的链对象s,在s之外运行意味着s.running_in_this_thread()返回false。 如果调用线程正在执行通过post()dispatch()wrap()提交到链的处理程序,这将返回true。 否则,它将返回false

io_service.post(handler);              // handler will run outside of strand
strand.post(handler);                  // handler will run inside of strand
strand.dispatch(handler);              // handler will run inside of strand
io_service.post(strand.wrap(handler)); // handler will run inside of strand

鉴于:

  • 一个链对象s
  • 通过s.post()添加到 strands的函数对象f1,或在s.running_in_this_thread() == falses.dispatch()
  • 通过
  • s.post()添加到 strands的函数对象f2,或在s.running_in_this_thread() == falses.dispatch()

然后,链提供了排序和非并发的保证,这样f1f2就不会同时被调用。 此外,如果f1的添加发生在添加f2之前,则f1将在f2之前被调用。