【发布时间】:2010-12-21 22:02:20
【问题描述】:
A(很久以前)我写了一个多线程的网络蜘蛛,以使并发请求能够同时发生。那是在我的 Python 青年时代,在我知道 GIL 以及它为多线程代码(IE,大多数时候东西最终被序列化!)带来的相关问题之前的日子......
我想重新编写此代码,使其更健壮且性能更好。基本上有两种方法可以做到这一点:我可以在 2.6+ 中使用新的multiprocessing module,或者我可以使用某种基于反应器/事件的模型。我宁愿选择后者,因为它更简单且不易出错。
所以问题与最适合我的需求的框架有关。以下是我目前所知道的选项列表:
- Twisted:Python 反应器框架的鼻祖:看起来很复杂而且有点臃肿。小任务的陡峭学习曲线。
- Eventlet:来自lindenlab 的人。面向此类任务的基于 Greenlet 的框架。不过我看了一下代码,它不是很漂亮:不符合 pep8,散布着打印(为什么人们在框架中这样做!?),API 似乎有点不一致。
- PyEv: 不成熟,虽然它是基于 libevent 的,但现在似乎没有人在使用它,所以它有一个可靠的后端。
- asyncore:来自标准库:über 低级,似乎需要大量的跑腿工作才能让某些东西落地。
- tornado:虽然这是一个面向服务器的产品,旨在为动态网站提供服务,但它确实具有async HTTP client 和一个简单的ioloop。看起来它可以完成工作,但不是它的预期目的。 [编辑:不幸的是,它不能在 Windows 上运行,这对我来说很重要——我需要支持这个蹩脚的平台]
我有什么遗漏的吗?肯定有一个库可以满足简化的异步网络库的最佳选择!
[编辑:非常感谢intgr 指向this page。如果您滚动到底部,您会看到一个非常好的项目列表,旨在以一种或另一种方式解决此任务。实际上,自 Twisted 成立以来,事情似乎确实在发生变化:人们现在似乎更喜欢基于 co-routine 的解决方案,而不是传统的面向反应器/回调的解决方案。这种方法的好处是代码更清晰更直接:我过去确实发现,尤其是在使用 C++ 中的boost.asio 时,基于回调的代码可能会导致设计难以遵循并且相对晦涩难懂未经训练的眼睛。使用协同例程可以让您编写至少看起来更同步的代码。我想现在我的任务是找出我喜欢这些库中的哪个外观并试一试!很高兴我现在问...]
[编辑:任何关注或偶然发现此问题或在任何意义上关心此主题的人都可能感兴趣:我为这项工作找到了一篇非常棒的关于the available tools 当前状态的文章]
【问题讨论】:
-
Python 是多线程的,它只是不允许两个线程同时运行 Python 代码。
-
我从你的问题中学到的比从答案中学到的要多。
-
@Denis:呵呵,谢谢!答案中也有一些很好的指示,特别是 intgr。我知道很多选项,而且我不只是想要这些答案,所以我想我会不厌其烦地拼出我所知道的:)
-
> 人们现在似乎更喜欢基于协同程序的解决方案,而不是传统的反应器/面向回调的解决方案。这不是一个明智的比较。 “基于协同程序的解决方案”和“面向反应器”的解决方案是正交的。 (忽略 Python 没有协程的事实)看看 Twisted 的 inlineCallbacks,看看如何通过健壮、成熟的网络层拥有您似乎更喜欢的编程风格,不会让您接触到复杂的平台特质。跨度>
-
补充几点: 1. Tornado 在 Windows 上运行良好。它的性能和可扩展性不高,因为它使用
select进行 I/O 多路复用。但是您应该能够使用tornado-pyuv 从中获得不错的性能。 2. Python 3.3+ 现在有 asyncio 和它的 backport trollius 允许在它的事件循环中运行任何 Tornado 应用程序(很快就会支持 Twisted)。
标签: python networking twisted asynchronous