很久以前我写了一个我多线程的网络蜘蛛,以便同时发生并发请求.那是在我的Python青年时代,在我知道GIL及其为多线程代码创建的相关问题之前的几天(IE,大多数时候东西最终都被序列化了!)......
我想重做这段代码,使其更强大,性能更好.我基本上有两种方法可以做到这一点:我可以在2.6+中使用新的多处理模块,或者我可以选择某种类型的基于反应器/事件的模型.我宁愿做后者,因为它更简单,更不容易出错.
所以问题涉及哪种框架最适合我的需求.以下是我目前了解的选项列表:
Twisted:Python反应器框架的祖父:看起来很复杂而且有点臃肿.小任务的陡峭学习曲线.
Eventlet:来自lindenlab的人.基于Greenlet的框架,适用于这些类型的任务.我看了一下代码,但它并不太漂亮:非pep8兼容,分散打印(人们为什么要在框架中执行此操作!?),API似乎有些不一致.
PyEv:不成熟,现在似乎没有人使用它虽然它基于libevent所以它有一个坚实的后端.
asyncore:来自stdlib:über低级别,看起来很多涉及到的事情只是为了得到一些实际的东西.
龙卷风:虽然这是面向服务器的产品,旨在服务于动态网站,但它确实具有异步HTTP客户端和简单的ioloop.看起来它可以完成工作但不是它的目的.[编辑:不幸在Windows上运行,这对我来说很重要 - 这是我支持这个蹩脚平台的要求]
我有什么遗漏吗?当然必须有一个适合简化的异步网络库的最佳点的库!
[编辑:非常感谢intgr指向此页面的指针.如果你滚动到底部,你会看到有一个非常好的项目列表,旨在以某种方式解决这个任务.事实上,自Twisted开始以来事情确实已经发生了变化:人们现在似乎更倾向于基于协同例程的解决方案而不是传统的反应堆/回调导向解决方案.这种方法的好处是更清晰,更直接的代码:我在过去肯定发现过,特别是在C++中使用boost.asio时,基于回调的代码可能会导致难以理解的设计并且相对模糊不清未经训练的眼睛.使用协同例程允许您编写至少看起来更加同步的代码.我想我现在的任务是找出我喜欢的这些库中的哪一个,并试一试!很高兴我现在问...]
[编辑:也许对任何跟随或偶然发现这个问题或者在任何意义上关心这个话题的人都感兴趣:我发现了一个非常好的关于这个工作的可用工具的当前状态的文章]
扭曲是复杂的,你是对的.扭曲并不臃肿.
如果你到这里看看:http://twistedmatrix.com/trac/browser/trunk/twisted你会发现一个有组织的,全面的,和很好的测试套件许多互联网的协议,以及辅助代码来写并部署非常复杂的网络应用程序 我不会把膨胀与全面性混为一谈.
众所周知,Twisted文档从初看起并不是最方便用户的,我相信这会让一些不幸的人失望.但如果你投入时间,扭曲是惊人的(恕我直言).我做了,它证明是值得的,我建议其他人尝试相同的.
gevent是事件清理.
API-wise它遵循与标准库(特别是线程和多处理模块)相同的约定.因此,您可以使用Queue和Event等熟悉的东西.
它只支持libevent(update: libev from 1.0)作为reactor实现,但充分利用它,具有基于libevent-http的快速WSGI服务器,并通过libevent-dns解析DNS查询,而不是像大多数其他库那样使用线程池做.(更新:因为1.0 c-ares用于进行异步DNS查询;线程池也是一个选项.)
与eventlet一样,它使用greenlet使回调和Deferred成为不必要的.
查看示例:并行下载多个URL,长轮询网聊.
我喜欢并发 Python模块,它依赖于Stackless Python微线程或Greenlets来实现轻量级线程.所有阻塞网络I/O都通过单个libevent
循环透明地进行异步,因此它应该与真正的异步服务器一样高效.
我想这种方式类似于Eventlet.
缺点是它的API与Python的sockets
/ threading
模块完全不同; 你需要重写你的应用程序(或写一个兼容性填充层)
编辑:似乎还有一些类似的cogen,但是使用Python 2.5的增强型生成器来代替它的协程,而不是Greenlets.这使得它比并发和其他替代方案更便携.网络I/O直接使用epoll/kqueue/iocp完成.
NicholasPiël在他的博客上编写了一个非常有趣的比较这些框架:非常值得一读!
这些解决方案都不会避免GIL阻止CPU并行性这一事实 - 它们只是获得线程已经拥有的IO并行性的更好方法.如果你认为你可以做得更好IO,那么一定要追求其中的一个,但如果你的瓶颈在于处理结果,除了多处理模块之外,这里的任何事都没有用.
我不会打电话给Twisted臃肿,但很难绕开你的脑袋.我避免真正解决了很长一段时间的学习,因为我总是希望"小任务"更容易一些.
然而,现在我已经使用了它,我不得不说包含所有电池非常好.
我所使用的所有其他异步库最终都不像它们出现的那样成熟.Twisted的事件循环是可靠的.
我不太确定如何解决陡峭的扭曲学习曲线.如果有人将它分叉并清理一些东西,比如删除所有向后兼容性和死亡项目,这可能会有所帮助.但我认为这就是成熟软件的本质.
Kamaelia尚未被提及.它的并发模型基于将组件连接在一起,并在收件箱和发件箱之间传递消息.这是一个简短的概述.
我开始使用扭曲的东西.它的美丽几乎是因为它"臃肿".几乎所有的主要协议都有连接器.您可以拥有一个jabber机器人,它将接收命令并发布到irc服务器,通过电子邮件发送给某人,运行命令,从NNTP服务器读取以及监视网页以进行更改.坏消息是,它可以做到这一切,并且可以使事情过于复杂,如OP解释的简单任务.python的优点是你只包含你需要的东西.因此,虽然下载量可能是20mb,但您可能只包含2mb的库(这仍然很多).我对twisted的最大抱怨是虽然它们包含了一些示例,但除了基本的tcp服务器之外,还有其他任何东西.
虽然不是python解决方案,但我已经看到node.js最近获得了更多的牵引力.事实上,我已经考虑过为较小的项目进行调查但是当我听到javascript时我只是畏缩:)