干净,轻巧的替代Python的替代品吗?[关闭]


222

一个(很久以前),我写了一个网络蜘蛛,对它进行了多线程处理,以使并发请求能够同时发生。那是我的Python青年时代,在我了解GIL及其为多线程代码造成的相关麻烦之前(IE,大多数情况下,这些东西最终都被序列化了!)...

我想对这段代码进行重做,以使其更健壮并性能更好。基本上有两种方法可以执行此操作:我可以使用2.6+中的新多处理模块,也可以使用某种基于反应堆/事件的模型。我宁愿稍后再做,因为它更加简单且不易出错。

因此,问题与哪种框架最适合我的需求有关。以下是到目前为止我所知道的选项列表:

  • Twisted:Python反应器框架的祖父:看起来很复杂,但是有点a肿。陡峭的学习曲线,可完成一项小任务。
  • Eventlet:从在家伙lindenlab。基于Greenlet的框架,适用于此类任务。我看了一下代码,但看起来不是很漂亮:不符合pep8,散布着印刷品(为什么人们要在框架中这样做!?),API似乎有点不一致。
  • PyEv:不成熟,尽管它基于libevent,所以现在似乎还没有人在使用它,因此它有一个可靠的后端。
  • asyncore:来自stdlib:über低级,似乎涉及很多工作,只是为了使事情起步。
  • 龙卷风:尽管这是一种面向服务器的产品,旨在为动态网站提供服务器,但它确实具有异步HTTP客户端和简单的ioloop。看起来可以完成工作,但不能达到预期目的。[编辑:不幸的是,它不能在Windows上运行,这对我来说算是它了-这是我支持这个la脚平台的要求]

我有什么想念的吗?当然,必须有一个适合简化异步网络库的最佳选择的库!

[编辑:非常感谢intgr指向此页面。如果滚动到底部,您将看到一个非常不错的项目列表,旨在以一种或多种方式解决此任务。实际上,自Twisted诞生以来,事情确实已经发生了变化:人们现在似乎更喜欢基于协同例程的解决方案,而不是传统的面向反应器/回调的解决方案。这种方法的好处是更直接的代码:我过去确实发现过,特别是在使用boost.asio时。在C ++中,基于回调的代码可能导致难以遵循的设计,并且对于未经训练的人来说是相对模糊的。使用协同例程可使您编写看起来至少同步一些的代码。我想现在我的任务是找出我喜欢的众多库中的哪一个,并尝试一下!很高兴我现在问...]

[编辑:可能是关注或偶然发现此问题或在某种意义上关心此主题的任何人所感兴趣的:我发现了该工作可用工具的当前状态非常出色的文章]


14
Python 多线程的,它只是不允许两个线程同时运行Python代码。
intgr

86
我从你的问题中学到了很多,而不是从答案中学到了很多。
Denis Otkidach,2009年

2
@Denis:嘿,谢谢!答案中也有一些很好的指针,特别是intgr的。我知道那里有很多选择,我不只是想要答案,所以我想我会麻烦说出我所知道的:)
jkp

5
>人们现在似乎更喜欢基于协同例程的解决方案,而不是传统的面向反应器/回调的解决方案。这不是明智的比较。“基于常规程序的解决方案”和“面向反应器的”解决方案是正交的。(忽略Python没有协程这一事实),看看Twisted的inlineCallbacks,看看如何通过健壮,成熟的网络层拥有自己似乎更喜欢的编程风格,而不会使您面临复杂的平台特质。
Jean-Paul Calderone

2
需要补充的几点:1. Tornado在Windows上可以很好地运行。它不具有高性能和可扩展性,因为它select用于I / O复用。但是您应该能够使用tornado-pyuv获得不错的性能。2. Python 3.3+中现在有了asyncio,它的backport trollius允许在其事件循环中运行任何Tornado应用程序(很快将支持Twisted)。
schlamar 2014年

Answers:


28

我喜欢并发 Python模块,该模块依赖轻量级线程的Stackless Python微线程或Greenlets。所有阻塞网络I / O通过一个libevent循环透明地实现异步,因此它的效率应与真正的异步服务器差不多。

我想它在这种方式上类似于Eventlet。

缺点是其API与Python的sockets/ threading模块完全不同;您需要重写您的应用程序的一部分(或编写一个兼容性填充层)

编辑:似乎也有cogen,这是相似的,但是使用Python 2.5的增强型生成器为其协程而不是Greenlets。这使得它比并发和其他替代方法更可移植。网络I / O直接通过epoll / kqueue / iocp完成。


@intgr:很棒的链接。我曾经不时见过这两种东西,这些都是我希望看到的东西。+1
jkp

3
似乎并发是一个死项目,它们是四年前的最后更新。
Gewthen

项目已经死了,Hyves也死了!
巴哈迪尔

1
自Python 2.5以来发生了很多事情。Python 3.5中的asyncio很棒。
Joseph Sheedy

99

扭曲是复杂的,您是正确的。扭曲肿。

如果您在此处查看:http : //twistedmatrix.com/trac/browser/trunk/twisted,您将找到一个组织良好,全面且经过良好测试的,包含许多 Internet协议的套件,以及编写的辅助代码并部署非常复杂的网络应用程序。我不会将膨胀与全面性混为一谈。

众所周知,Twisted文档乍一看并不是最用户友好的,并且我相信这会避免不幸的人们。但是如果您花时间的话,Twisted太棒了(IMHO)。我做到了,事实证明这是值得的,我建议其他人也可以尝试。


4
@clemesha:也许您是对的,并且没有被加载,但是确实感觉有太多东西让我无法做简单的事情。我了解异步编程,我在C ++中使用boost :: asio进行工作,因此这些概念并不是新概念,但它与扭曲事物相辅相成:这是一个全新的世界,就像django用于Web一样。再次,当我在做网络工作时,我使用轻量级的WSGI代码,并且仅将我需要的内容组合在一起。我猜课程是马。
jkp

7
@clemesha:嗯,我今天跳水了一下:扭曲重达20MB!甚至核心是12MB。...如果还不肿,我不确定是什么。
jkp

29
基本的Twisted API很小(反应堆,延迟,协议)。大多数Twisted代码都是使用这些基础知识的异步协议实现。“膨胀”在这里不是有用的形容词(或者在大多数情况下实际上不是)。Twisted的大小对于它所做的工作量是合理的。
daf

56

gevent清除eventlet

在API方面,它遵循与标准库(尤其是线程和多处理模块)相同的约定(在这里有意义)。因此,您可以使用诸如QueueEvent之类的熟悉的东西。

它仅支持libevent从1.0开始更新: libev)作为反应堆实现,但充分利用了它的优点,它具有基于libevent-http的快速WSGI服务器,并通过libevent-dns解决DNS查询,而不是像其他大多数库一样使用线程池做。(更新:由于使用1.0 c-ares进行异步DNS查询;线程池也是一种选择。)

与eventlet一样,它通过使用greenlets使得不需要回调和Deferreds 。

查看示例:并发下载多个URL长时间轮询webchat


4
我要讲第二个gevent-在审查了许多解决方案之后,gevent对我来说非常有效。它使我能够保留现有程序的大部分内容,而所需的更改却微不足道-最重要的是,如果代码需要在3、4、5,...年的时间内维护,那么它仍然可以对于任何不熟悉gevent的人来说,Twisted最大的优势就是强大的学习曲线,这不仅会在实施过程中引起问题,还会在维护过程中
带来麻烦

27

NicholasPiël在他的博客上对这些框架进行了非常有趣的比较:值得一读!


2
我同意这篇文章是有趣的读物,但我认为值得考虑所提供基准的有效性。查看评论在这里:reddit.com/r/programming/comments/ahepg/...
clemesha

1
@clemesha,尽管该reddit页面中的要点值得注意,但基准测试是在双核计算机上完成的,可能没有遭受描述的致命缺陷的困扰。我想这是有可能在同一个核心客户端和服务器运行,但它似乎并不可能。
彼得·汉森

15

这些解决方案都无法避免GIL阻止CPU并行的事实-它们只是获得线程已经具有的IO并行的更好方法。如果您认为可以做得更好的IO,则可以采取以下任何一种方法,但是如果瓶颈是处理结果,那么除了多处理模块之外,这里没有任何帮助。


使用多个流程有什么问题?
埃米尔·伊万诺夫

3
没什么,因此建议使用多重处理模块。
亚当·赫普

11

我不会说Twisted blo肿,但很难缠住你的头。我一直避免真正地学会学习,因为我一直希望对“小任务”更轻松一些。

但是,既然我已经使用了它,我不得不说所有的电池都非常好。

我使用过的所有其他异步库最终都没有看起来那么成熟。Twisted的事件循环很稳定。

我不太确定如何解决陡峭的Twisted学习曲线。如果有人将其分叉并清理一些东西,例如删除所有向后兼容的废纸and和无效项目,那可能会有所帮助。但这就是成熟软件的本质。


如果您曾经查看过如何在Windows下实现gtk反应器(每10毫秒进行一次核心轮询:twistedmatrix.com/trac/browser/trunk/twisted/internet/…),那么您就不会称其为“成熟” ...
schlamar

2
嗨@schlamar。早在人们对功率效率的关注减少很多的时候,这种讨厌的黑客就被用作GTK +中一些非常严重的错误的解决方法。但是,Twisted的优点在于,我们可以一次拥有此bug ,然后在框架中对其进行修复,而我们的用户则无需担心。您是否想提供一个解决此问题并摆脱(弃用(先删除然后再删除))的修补程序PortableGtkReactor
雕文

1
@Glyph 如果有人要解决此问题,我会在twistedmatrix.com/trac/ticket/4744#comment:2上添加有用的建议,因为其中某些问题仍然存在。顺便说一句,您可以通过在两个事件循环之间安排回调来更有效地解决此问题。
schlamar 2014年


7

我开始在某些事情上使用扭曲。它的美丽几乎是因为它“ blo肿”。那里有几乎所有主要协议的连接器。您可以拥有一个jabber机器人,该机器人将接收命令并将其发布到irc服务器,将其通过电子邮件发送给某人,运行命令,从NNTP服务器读取以及监视网页中的更改。坏消息是它可以完成所有这些操作,并且会使诸如OP所述的简单任务变得过于复杂。python的优点是您只包含需要的内容。因此,尽管下载量可能是20mb,但您可能只包含2mb的库(仍然很多)。我最大的困惑是,尽管它们包含示例,但您只能依靠基本的tcp服务器。

虽然不是python解决方案,但最近我已经看到node.js获得了更多的吸引力。实际上,我已经考虑过将其用于较小的项目,但是当我听到javascript时我只是畏缩:)


我是Python的忠实粉丝。–观看道格拉斯·克罗克福德(Douglas Crockford)的“ Javascript –好的部分”(3、4个视频)。并查看CoffeeScript。事实证明,JS具有Python应该具有的东西,除了语法之外,哈哈。CS试图缓解这种情况,但是对此有点笨拙……
Robert Siemer

4

关于这一主题的一本好书是:Abe Fettig撰写的“ Twisted Network Programming Essentials”。这些示例说明了如何编写非常Pythonic的代码,对我个人而言,不要以strike肿的框架为基础。看书中的解决方案,如果它们不是干净的,那么我不知道干净意味着什么。

我唯一的困惑与其他框架(如Ruby)相同。我担心,它会扩大规模吗?我不愿意将客户端委托给将存在可伸缩性问题的框架。


4

Whizzer是一个使用pyev的微型异步套接字框架。它的速度非常快,主要是因为pyev。它试图提供类似的界面,但略有改动。


2

也可以尝试Syncless。它基于协程(因此类似于Concurrence,Eventlet和gevent)。它实现了socket.socket,socket.gethostbyname(等),ssl.SSLSocket,time.sleep和select.select的插入式非阻塞替换。它很快。它需要Stackless Python和libevent。它包含一个用C编写的强制性Python扩展(Pyrex / Cython)。


2

我确认不同步的好处。它可以使用libev(libevent的更新,更干净,性能更好的版本)。有时它没有libevent所提供的支持,但是现在开发过程更进一步,非常有用。


1

如果您只想要一个简化的,轻量级的HTTP请求库,那么我觉得Unirest真的很好


0

欢迎您来看看PyWorks,它采用了完全不同的方法。它使对象实例在其自己的线程中运行,并对该对象进行异步函数调用。

只需让一个类从Task继承而不是从Object继承,它就异步了,所有方法调用都是Proxies。返回值(如果需要)是将来的代理。

res = obj.method( args )
# code continues here without waiting for method to finish
do_something_else( )
print "Result = %d" % res # Code will block here, if res not calculated yet

可以在http://bitbucket.org/raindog/pyworks上找到PyWorks。


1
尽管这很有趣并且可能适合某些任务,但是使用线程进行网络连接会产生不好的效果(尤其是由于GIL而在Python上)。这正是问题所在:事件框架或多处理。因此,您的答案显然超出了范围……
schlamar 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.