libev和libevent有什么区别?

What's the difference between libev and libevent?

这两个库都是为异步I / O调度而设计的,都在Linux上使用epoll,在FreeBSD上使用kqueue等。

除了表面上的区别,我的意思是这两个库之间的真正区别是什么? 关于建筑还是设计理念?


至于设计哲学,libev的创建是为了改进libevent中的某些体系结构决策,例如,全局变量的使用使在多线程环境中安全使用libevent变得困难,观察器结构很大,因为它们结合了I / O,时间和信号在一个处理程序中,诸如http和dns服务器之类的额外组件遭受了较差的实现质量和随之而来的安全性问题,并且计时器不精确并且不能很好地应对时间跨度。

Libev尝试通过不使用全局变量,而是对所有函数使用循环上下文,通过对每种事件类型使用小型观察程序来改善上述每一项(I / O监视程序在x86_64上使用56个字节,而在libevent中使用136个字节),事件类型,例如基于墙上时钟与单调时间的计时器,线程间中断,准备和检查观察程序以嵌入其他事件循环或将其嵌入等等。

额外的组件问题是通过根本不使用它们来"解决"的,因此libev可能很小而又有效,但是您还需要在其他地方查找http库,因为libev根本没有一个(例如,有一个一个非常相关的库libeio,它执行异步I / O,可以独立使用,也可以与libev一起使用,因此可以混合使用。

简而言之,libev尝试仅做一件事(POSIX事件库),而这可能是最有效的方式。 Libevent尝试为您提供完整的解决方案(事件库,非阻塞I / O库,http服务器,DNS客户端)。

或者,更简短地说,libev尝试遵循UNIX工具箱哲学,即尽可能做到最好。

请注意,这就是设计理念,因为我设计了libev,所以我可以权威地说一下。是否实际达到这些设计目标,还是哲学是否基于合理的原则,将由您来判断。

2017年更新:

我多次被问到我指的是定时器不精确,为什么libev在Windows上不支持IOCP。

至于计时器,libevent会相对于将来某个未知的基准时间来调度计时器,而您可能并不知道。 Libev可以提前告诉您它将用于安排计时器的基本时间,这使程序可以同时使用libevent方法和libev方法。此外,libevent有时有时会提前终止计时器,具体取决于后端。前者是一个API问题,后者是可修复的(并且可能由于(我未检查)而已修复)。

至于IOCP支持-我认为这是不可能完成的,因为IOCP根本不够强大。一方面,他们需要一种特殊的套接字类型,这将进一步限制Windows上允许的句柄集(例如,perl使用的套接字对于IOCP而言是"错误的"类型)。此外,IOCP根本不支持I / O准备事件,它们只能执行实际的I / O。对于某些句柄类型,有一些变通办法,例如进行虚拟的0字节读取,但这又会限制您可以在Windows上使用的句柄类型,甚至还会依赖于未记录在案的行为,该行为可能并非所有套接字提供程序都共享。

据我所知,没有其他事件库也支持Windows上的IOCP。 libevent的作用是,除了事件库之外,它还允许您将读取/写入操作排队,然后可以通过IOCP来完成。由于libev不会为您执行I / O,因此无法在libev本身中使用IOCP。

这确实是设计使然-libev试图变得小巧且类似于POSIX,而Windows根本没有有效的方法来获取POSIX风格的I / O事件。如果IOCP很重要,则您必须自己使用它们,或者确实使用许多其他为您执行I / O的框架,因此可以使用IOCP。


对我而言,libevent的最大优势是内置的OpenSSL支持。在libevent API的2.0版本中引入的Bufferevent接口对开发人员而言几乎可以轻松处理安全连接。
可能是我的知识已经过时了,但是libev似乎不支持这一点。