你能在 libev 中对事件进行优先排序吗?

Can you prioritize events in libev?

假设我有 2 个正在监视事件的套接字,我真的希望首选套接字 1(即使以耗尽套接字 2 为代价)。我如何用 libev 做到这一点(我问了关于 libuv 的同样问题 here 但看起来 libuv 不能那样做)?

作为使用 libevent 的示例,可以使用:

int event_priority_set(struct event *event, int priority);

When multiple events of multiple priorities become active, the low-priority events are not run. Instead, Libevent runs the high priority events, then checks for events again. Only when no high-priority events are active are the low-priority events run.

检查 libev 函数 ev_set_priority():

ev_set_priority (ev_TYPE *watcher, int priority)

Set and query the priority of the watcher. The priority is a small integer between EV_MAXPRI (default: 2) and EV_MINPRI (default: -2). Pending watchers with higher priority will be invoked before watchers with lower priority, but priority will not keep watchers from being executed (except for ev_idle watchers).

http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod#GENERIC_WATCHER_FUNCTIONS

ev_set_priority,尽管有这个名字,但它本身并没有做你想做的事情,它只是改变了回调调用的相对顺序,有一个例外:ev_idle watchers.

对于 ev_idle 观察者,当其他事件或更高优先级的空闲观察者挂起时,确实不会调用较低优先级的观察者。例如,ev_idle 个优先级为 0 的观察者将在没有其他优先级为 0(默认)的未决观察者时被处理,即只有当没有其他优先级为 0 的事件未决时才会调用它。 Libev 将在做出此决定之前检查更多事件,因此只要存在优先级为 0 或更高的事件,它就不会调用优先级为 0 或更低的空闲观察者。

解决您的问题的一种方法是只在 io 回调中为您的非首选套接字启动一个 ev_idle 观察者,其优先级等于 io 观察者的优先级,导致它无法处理直到处理完所有其他事件。

一个细微的变化是在某种集合中标记您的低优先级 io 观察者并启动一个 ev_idle 观察者,然后它通过您集合中的所有套接字。

另一种完全不同的方法是查看可嵌入的事件循环并将所有优先级较低的 io 观察器移至嵌入式循环中。在您的 ev_embed 观察者回调中,您可以启动一个空闲观察者稍后调用 ev_embed_sweep。这样做的好处是需要更少的空闲观察者并将低优先级套接字的所有处理转移到它们自己的事件循环中,因此它们不会为您的高优先级 io 观察者造成额外的延迟问题。