延迟回调
默认情况下,当相应的条件发生时,会立即执行bufferevent回调。(evbuffer回调也是如此;当依赖关系变得复杂时,这种立即调用可能会带来麻烦。例如,假设有一个回调函数在evbuffer A变空时将数据移入其中,另一个回调函数在evbuffer A变满时处理evbuffer A中的数据。* 由于这些调用都发生在堆栈上,如果依赖关系变得足够严重,您可能会面临堆栈溢出的风险。
为了解决这个问题,你可以告诉一个bufferevent(或evbuffer)它的回调应该被延迟。当满足延迟回调的条件时,不是立即调用它,而是将其作为event_loop()调用的一部分排队,并在常规事件的回调之后调用。
如上所述:
1.事件循环获取一批事件,并立即逐个处理它们。
1.在提取的事件被处理之前,任何新事件都不会被提取和处理。
1.如果一个事件被标记为BEV_OPT_DEFER_CALLBACKS
,那么它将在同一批中的所有其他事件被处理之后被处理。
提供了两个回调ca
和cb
。首先,调用ca
,ca
发现evbuffer_A
为空,然后向其中写入消息。
然后,调用cb
,cb
发现evbuffer_A
包含一条消息,然后获取并发送出去。
当调用cb
时,ca
的堆栈已经被释放。我认为在这种情况下不会出现堆栈溢出。
所以我的问题是
libevent中延迟回调的目的是什么?
1条答案
按热度按时间xu3bshqb1#
在引用的文本中给出的示例是在一个事件之后填充缓冲器并且在另一个事件之后清空缓冲器。
考虑同一示例的此非事件驱动的伪代码。
字符串
显然,两个
if
语句的条件总是为真。因此,这些函数永远不会完成,而是一次又一次地相互调用。堆栈迟早会溢出。现在想象一个事件驱动的系统,其中所有回调都会在事件触发时发生(即删除
if
-语句,但请记住,事件系统与if
-语句的作用相同)。比如:型
这样的系统将与非事件驱动的伪代码(即,在第一个回调完成之前调用下一个回调。
延迟回调可以通过让一个回调在调用下一个回调之前完成来解决这个问题。