Libevent - 运行循环(event_base_loop)
Posted
技术标签:
【中文标题】Libevent - 运行循环(event_base_loop)【英文标题】:Libevent - Running the loop(event_base_loop) 【发布时间】:2022-01-22 16:39:47 【问题描述】:请告诉我,这是来自 Nick Mathewson 的book on Libevent 的参考第 3 节(“Running an event loop”)的引述:
默认情况下,event_base_loop() 函数运行 event_base 直到 没有更多的事件在其中注册。
老实说,我就是无法理解这句话。
什么意思 - “直到没有更多事件注册”。
循环如何知道没有更多新事件?事件之间可以有一个时间间隔 - 1 秒、1 小时......
Libevent 如何知道事件已经结束?
PS:我正在尝试将 event_base_loop () 函数的工作与 Windows 上的 GetQueuedCompletionStatus () 函数进行比较,但我不明白。因为 GetQueuedCompletionStatus 在无限循环中工作 - 无论是否有事件 - GetQueuedCompletionStatus 等待一个无限新的事件,如果没有则不会完成。
PS1:我很着急,没有完成“使用事件循环”一章。
它说你可以通过在第二个参数EVLOOP_NO_EXIT_ON_EMPTY中传递一个标志来重新定义event_base_loop()函数的行为。
这意味着该函数将无限期地等待新事件,或者直到我想通过 event_base_loopbreak / event_base_loopexit 手动退出 event_base_loop () 循环。
【问题讨论】:
像“......直到没有更多的当前事件......”一样阅读它 current wording 似乎是“默认情况下,此循环将运行事件库,直到没有更多未决或活动事件,或者直到调用 event_base_loopbreak() 或 event_base_loopexit()。你可以使用 'flags' 参数覆盖此行为。" @某程序员老兄,但毕竟当我启动event_base_loop时,可能还没有事件。即使有 - 那么当所有当前事件结束时 - 在它们之后,例如,1分钟后,其他事件可能会出现吗?我就是想不通:( Re "当我启动 event_base_loop 时,可能还没有事件。",没有事件意味着没有挂起或活动的事件,所以文档表明它会在那时返回. @ikegami,我正在尝试将 event_base_loop () 函数的工作与 Windows 上的 GetQueuedCompletionStatus () 函数进行比较,但我不明白。因为 GetQueuedCompletionStatus 在无限循环中工作 - 无论是否有事件 - GetQueuedCompletionStatus 等待一个无限新的事件,如果没有则不会完成。 【参考方案1】:注意它说“没有更多的事件注册”,而不是“没有更多的事件”。默认情况下,事件循环将在事件库运行为空时退出,即使以后可能会发生更多事件。这将在本章后面以不同的方式重述:
通常,一旦没有待处理或活动的事件,循环就会退出。
在event_base_loop()
的 API 文档中:
默认情况下,此循环将运行事件库,直到没有更多未决或活动的事件,或者直到调用 event_base_loopbreak() 或 event_base_loopexit()。
如问题中所述,EVLOOP_NO_EXIT_ON_EMPTY
可以更改此行为,使其更像典型的事件队列,等待事件(除非设置了EVLOOP_NONBLOCK
)并在它们到达时分派它们。
“Running an event loop”包含event_base_loop()
的伪代码,这也应该有助于澄清行为。
相比之下,GetQueuedCompletionStatus
将等待和操作单个数据包(注意:等待不太可能是busyloop,而是基于其他一些多任务技术,例如中断和线程同步原语;确切的方法是一个实现细节,不应该影响使用)。它与带有标志EVLOOP_ONCE | EVLOOP_NO_EXIT_ON_EMPTY
的event_base_loop()
最相似,尽管event_base_loop
可能会处理多个具有相同优先级的事件,如果它们恰好在第一个事件完全处理之前进入。从另一个方向来看,如果将 dwMilliseconds
参数传递给 GetQueuedCompletionStatus
的值为 0,则其行为类似于 event_base_loop()
的默认行为,如果 I/O 完成队列中没有数据包则立即退出。
【讨论】:
这是一个很好的解释。混淆的主要来源可能是 OP 似乎认为 Libevent“event_base_loop()”(或类似地,“event_base_dispatch()”)的行为就像 Win32 GetQueuedCompletionStatus()。以上是关于Libevent - 运行循环(event_base_loop)的主要内容,如果未能解决你的问题,请参考以下文章
ReactPHP libevent 和 socket_pair 抛出错误