两个lib都是为异步i / o调度而设计的,都是在linux上使用epoll,在FreeBSD上使用kqueue等。
除了肤浅的差异,我的意思是这两个图书馆之间的真正区别是什么?关于建筑或设计哲学?
答案 0 :(得分:211)
至于设计理念,libev的创建是为了改进libevent中的一些体系结构决策,例如,全局变量使用使得很难在多线程环境中安全地使用libevent,观察者结构很大,因为它们结合了I / O,时间和信号处理程序合二为一,诸如http和dns服务器之类的额外组件遭受了糟糕的实现质量和由此产生的安全问题,并且定时器不精确且无法很好地应对时间跳跃。
Libev尝试通过不使用全局变量但通过对所有函数使用循环上下文来改进其中的每一个,通过对每个事件类型使用小观察者(I / O观察者在x86_64上使用56个字节,而在libevent中使用136个字节) ,允许额外的事件类型,如基于wallclock的计时器与单调时间,线程间中断,准备和检查观察者嵌入其他事件循环或嵌入等等。
额外的组件问题是通过不使用它们来“解决”,因此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使用的sopckets是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。
答案 1 :(得分:13)
libevent 对我来说的巨大优势是内置的OpenSSL支持。在2.0版本的 libevent API中引入的Bufferevent接口几乎可以轻松地为开发人员处理安全连接。 可能是我的知识已经过时但似乎 libev 不支持这一点。