Libev 和 libevent 有什么区别?

这两个库都是为异步 i/o 调度而设计的,它们都在 linux 上使用 epoll,在 FreeBSD 上使用 kqueue,等等。

除了表面上的差异,我的意思是这两个库之间真正的区别是什么? 关于架构或设计哲学?

44322 次浏览

As for design philosophy, libev was created to improve on some of the architectural decisions in libevent, for example, global variable usage made it hard to use libevent safely in multithreaded environments, watcher structures are big because they combine I/O, time and signal handlers in one, the extra components such as the http and dns servers suffered from bad implementation quality and resultant security issues, and timers were inexact and didn't cope well with time jumps.

Libev tried to improve each of these, by not using global variables but using a loop context for all functions, by using small watchers for each event type (an I/O watcher uses 56 bytes on x86_64 compared to 136 for libevent), allowing extra event types such as timers based on wallclock vs. monotonic time, inter-thread interruptions, prepare and check watchers to embed other event loops or to be embedded and so on.

The extra component problem is "solved" by not having them at all, so libev can be small and efficient, but you also need to look elsewhere for an http library, because libev simply doesn't have one (for example, there is a very related library called libeio that does asynchronous I/O, which can be used independently or together with libev, so you can mix and match).

So in short, libev tries to do one thing only (POSIX event library), and this in the most efficient way possible. Libevent tries to give you the full solution (event lib, non-blocking I/O library, http server, DNS client).

Or, even shorter, libev tries to follow the UNIX toolbox philosophy of doing one thing only, as good as possible.

Note that this is the design philosophy, which I can state with authority because I designed libev. Whether these design goals have actually been reached, or whether the philosophy is based on sound principles, is up to you to judge.

Update 2017:

I was asked multiple times what timer inexactness I refer to, and why libev doesn't support IOCPs on windows.

As for timers, libevent schedules timers relative to some unknown base time that is in the future, without you knowing it. Libev can tell you in advance what base time it will use to schedule timers, which allows programs to use both the libevent approach and the libev approach. Furthermore, libevent would sometimes expire timers early, depending on the backend. The former is an API issue, the latter is fixable (and might have been fixed since - I didn't check).

As for IOCP support - I don't think it can be done, as IOCPs are simply not powerful enough. For one thing, they need a special socket type, which would limit the set of handles allowed on windows even more (for example, the sopckets used by perl are of the "wrong" type for IOCPs). Furthermore, IOCPs simply don't support I/O readyness events at all, they only can do actual I/O. There are workarounds for some handle types, such as doing a dummy 0-byte read, but again, this would limit the handle types you can use on windows even more and furthermore would rely on undocumented behaviour that is likely not shared by all socket providers.

To my knowledge, no other event library supports IOCPs on windows, either. What libevent does is, in addition to the event library, it allows you to queue read/write operations which then can be done via IOCPs. Since libev does not do I/O for you, there is no way to use IOCPs in libev itself.

This is indeed by design - libev tries to be small and POSIX-like, and windows simply does not have an efficient way to get POSIX-style I/O events. If IOCPs are important, you either have to use them yourself, or indeed use some of the many other frameworks that do I/O for you and therefore can use IOCPs.

The great advantage of libevent for me is the built-in OpenSSL support. Bufferevent interface, introduced in 2.0 version of libevent API, handles the secure connections almost painlessly for the developer. May be my knowlege has gone out of date but it seems like libev does not support this.

Here are souce code link, libev: https://github.com/enki/libev libevent: https://github.com/libevent/libevent
I find the latest commitee of libev is 2015, but the livevent still have commitees untill July 2022, so a library have persons to maintain it is also important.