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
可以在线外调用......这正是我不理解的部分.
即使我在理解这个概念时遇到了一些麻烦,但是一旦我开始工作就变得清晰了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会为你做一些优化:
io_service
实例)调用它.当它在strand的当前执行上下文之外被调用时,就是在调用它时outside the strand
.因此,在这种outside
情况下,调度只会将处理程序排队,就像post
其他处理程序在队列中等待或直接调用它时,它可以保证它不会与可能正在运行的队列中的任何其他处理程序同时调用在那一刻的工作线程之一.更新:
正如评论部分所述,inside
意味着called within another handler
例如:我发布了一个处理程序A
并在该处理程序内,我正在做dispatch
另一个处理程序.现在,正如在#2中解释的那样,如果在绞线串行队列中没有其他处理程序等待,则将同步调用分派处理程序.如果不满足这个条件,那就意味着,dispatch
从中调用outside
.
dispatch
从outside
链中调用,即不在当前执行上下文中调用,则asio会检查它callstack
以查看其串行队列中是否存在任何其他处理程序正在运行.如果没有,那么它将直接同步调用该处理程序.因此,没有排队处理程序的成本(我认为也不会进行额外的分配,但不确定).让我们看看文档链接:
s.dispatch(a)发生在s.post(b)之前,其中前者在the strand之外执行
这意味着,如果dispatch
从当前run
OR 之外的某些OR 调用已经排队的其他处理程序,那么它需要将处理程序排入队列,它不能同步调用它.由于它是一个串行队列,a
之前会被执行b
.
曾经有过另一个呼叫s.dispatch(c)
随着A和B,但之前a
并b
(在上述顺序)排队,然后c
将得到执行之前a
和b
,但绝不b
可以得到之前执行a
.
希望这能清除你的怀疑.
对于给定的链对象s
,运行到外部 s
意味着s.running_in_this_thread()
返回false
。true
如果调用线程正在执行通过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
f1
s
s.post()
s.dispatch()
s.running_in_this_thread() == false
f2
s
s.post()
s.dispatch()
s.running_in_this_thread() == false
那么链提供了排序和非并发的保证,使得f1
和f2
不会被并发调用。此外,如果 的添加f1
发生在 的添加之前f2
,则 thenf1
将在 之前被调用f2
。
归档时间: |
|
查看次数: |
998 次 |
最近记录: |