链内是什么意思?

sta*_*tle 4 c++ boost-asio c++11

我现在正试图抓住我的手boost::asio.这样做,我继续阅读" 一个post/dispatch 内部外部调用链".不知怎的,我想不通怎么里面一股不同于通过一个链,因此不能把握调用链函数的概念链中的所有.

可能我的拼图中只缺少一小块.有人可以举个例子来说明对一条链的调用是在内部还是外部?

到目前为止,我认为我已经理解的是,通过一连串发布一些东西就是

m_strand.post(myfunctor);
Run Code Online (Sandbox Code Playgroud)

要么

m_strand.wrap(myfunctor);
io_svc.post(myfunctor); 
Run Code Online (Sandbox Code Playgroud)

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

如果在一个链内只是为了调用一个strand的函数,那么strand 该类的文档将毫无意义.它声明strand::post可以在线外调用......这正是我不理解的部分.

Aru*_*nmu 9

即使我在理解这个概念时遇到了一些麻烦,但是一旦我开始工作就变得清晰了libdispatch.它帮助我asio更好地映射事物.

现在让我们看看如何理解 strand.考虑strand作为handlers需要执行的串行队列.

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

这些工作线程来自哪里?从io_service创建链时传递的对象.就像是:

asio::strand s(io_serv_obj);
Run Code Online (Sandbox Code Playgroud)

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

回到strands,当你post是一个处理程序时,那个处理程序总是在我们谈到的串行队列中排队.工作线程将一个接一个地从队列中获取处理程序.

现在,当你这样做时dispatch,asio会为你做一些优化:

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

更新: 正如评论部分所述,inside意味着called within another handler例如:我发布了一个处理程序A并在该处理程序内,我正在做dispatch另一个处理程序.现在,正如在#2中解释的那样,如果在绞线串行队列中没有其他处理程序等待,则将同步调用分派处理程序.如果不满足这个条件,那就意味着,dispatch从中调用outside.

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

让我们看看文档链接:

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

这意味着,如果dispatch从当前runOR 之外的某些OR 调用已经排队的其他处理程序,那么它需要将处理程序排入队列,它不能同步调用它.由于它是一个串行队列,a之前会被执行b.

曾经有过另一个呼叫s.dispatch(c)随着A和B,但之前ab(在上述顺序)排队,然后c将得到执行之前ab,但绝不b可以得到之前执行a.

希望这能清除你的怀疑.


Tan*_*ury 2

对于给定的链对象s,运行到外部 s意味着s.running_in_this_thread()返回falsetrue如果调用线程正在执行通过post()dispatch()或提交到链的处理程序,则返回此值wrap()。否则,它返回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
Run Code Online (Sandbox Code Playgroud)

鉴于:

  • 一个链对象s
  • 通过,或当f1ss.post()s.dispatch()s.running_in_this_thread() == false
  • 通过,或当f2ss.post()s.dispatch()s.running_in_this_thread() == false

那么链提供了排序和非并发的保证,使得f1f2不会被并发调用。此外,如果 的添加f1发生在 的添加之前f2,则 thenf1将在 之前被调用f2