一个干净,轻量级的替代Python的扭曲?
(很久以前)我写了一个multithreading的web-spider来同时启用并发请求。 那是在我的Python青年时代,在我知道GIL以及它为multithreading代码(IE,大多数时候东西刚刚结束了序列化!
我想重写这个代码,使其更强大,性能更好。 基本上有两种方法可以做到这一点:我可以在2.6+中使用新的多处理模块 ,或者我可以使用某种基于反应器/事件的模型。 我宁愿做后来的事,因为它简单得多,也不太容易出错。
所以这个问题涉及到哪个框架最适合我的需求。 以下是我所知道的选项列表:
- 扭曲 :Python反应器框架的爷爷:看起来很复杂,有点臃肿。 陡峭的学习曲线为一个小任务。
- Eventlet :来自lindenlab的家伙。 基于Greenlet的框架,面向这些types的任务。 我看了一下代码,它不太漂亮:非pep8兼容,分散打印(为什么人们在一个框架中做这个?),API似乎有点不一致。
- PyEv :不成熟,现在似乎没有人使用它,虽然它是基于libevent,所以它有一个坚实的后端。
- asyncore :从stdlib:über低级,看起来像是很多legwork只涉及到一些东西。
- 龙卷风 :虽然这是一个面向服务器的产品devise服务器dynamic网站,它具有asynchronousHTTP客户端和一个简单的ioloopfunction 。 看起来它可以完成工作,但不是它的目标。 不幸的是,在Windows上不能运行,这对我来说很重要 – 这是我支持这个蹩脚平台的要求]
有什么我错过了吗? 当然,必须有一个图书馆,适合一个简化的asynchronousnetworking库的甜点!
非常感谢intgr指向这个页面的指针。 如果你滚动到底部,你会看到有一个非常好的项目列表,旨在以这样或那样的方式来解决这个任务。 事实上,自从Twisted诞生以来事情确实已经发生了变化:现在人们似乎喜欢基于协同程序的解决scheme,而不是传统的反应器/callback定向解决scheme。 这种方法的好处是更直接的代码:我以前肯定发现,特别是在C ++中使用boost.asio时,基于callback的代码可能会导致难以遵循的devise,并且相对比较模糊未经训练的眼睛。 使用协同例程可以让你编写至less看起来更加同步的代码。 我想现在我的任务是弄清楚我喜欢这些图书馆中的哪一个,然后放弃它! 很高兴我现在问…]
任何关注这个问题的人或许会对此感兴趣,或者在任何意义上关心这个话题:我发现了一个关于这个工作可用工具当前状态的非常好的写法]
我喜欢Python的兼容模块,它依靠Stackless Python microthreads或Greenlets来实现轻量级线程。 所有阻塞的networkingI / O通过一个libevent
循环透明地变为asynchronous,所以它应该和真正的asynchronous服务器一样高效。
我想这个和Eventlet类似。
缺点是它的API与Python的sockets
/ threading
模块完全不同。 你需要重写一些你的应用程序(或者写一个兼容性的匀场层)
编辑:似乎也有cogen ,这是相似的,但使用Python 2.5的增强发电机的协同,而不是Greenlets。 这使得它比并发和其他替代scheme更便于携带。 networkingI / O直接使用epoll / kqueue / iocp完成。
扭曲是复杂的,你是对的。 扭曲不膨胀。
如果你看看这里: http : //twistedmatrix.com/trac/browser/trunk/twisted,你会发现一个有组织的,全面的,很好的testing套件的互联网的许多协议,以及帮助代码写并部署非常复杂的networking应用。 我不会把膨胀与全面性混为一谈。
众所周知,Twisted文档从一开始就不是用户友好型的,我相信这会让一些不幸的人失望。 但是如果你投入时间,扭曲是惊人的(恕我直言)。 我做了,它被certificate是值得的,我build议其他人尝试相同的。
gevent是eventlet清理 。
在API方面,它遵循与标准库(特别是线程和多处理模块)相同的约定。 所以你有熟悉的事情,如队列和事件来处理。
它只支持libevent ( 自1.0版以来的libev )作为反应器实现,但充分利用了它的特点,基于libevent-http的快速WSGI服务器,并通过libevent-dnsparsingDNS查询,而不是像大多数其他库一样使用线程池做。 ( 更新:因为1.0 c-ares用于做asynchronousDNS查询; threadpool也是一个选项。)
像eventlet一样,它使用greenlet使得callback和Deferreds成为不必要的。
看看例子: 并发下载多个url , 长轮询网聊 。
NicholasPiël在他的博客上编写了一个非常有趣的框架比较 :非常值得一读!
这些解决scheme都不会避免GIL阻止CPU并行的事实 – 它们只是获得线程已有的IO并行性的更好方法。 如果你认为你可以做更好的IO,通过一切手段追求其中之一,但是如果你的瓶颈在处理结果,除了多处理模块之外,这里什么都不会有帮助。
我不会去叫扭曲的臃肿,但很难包围你的头。 我避免了一段时间的学习,因为我总是希望“小任务”更容易一些。
然而,现在我已经与它合作了,我不得不说,包括所有的电池都非常好。
我所使用的所有其他asynchronous库最终都不如以前那么成熟。 Twisted的事件循环是坚实的。
我不太清楚如何解决陡峭的Twisted学习曲线。 如果有人愿意把它分叉并清理一些东西,比如清除所有向后兼容性和死亡项目,这可能会有所帮助。 但是我猜这就是成熟软件的本质。
卡玛丽亚尚未提及。 其并发模型基于将收件箱和发件箱之间的消息传递组件连接在一起。 这里是一个简要的概述。
我已经开始使用扭曲的东西。 它的美丽几乎是因为它“臃肿”。 有关于任何主要协议的连接器。 你可以拥有一个jabber机器人,它将命令并发布到irc服务器,通过电子邮件发送给某人,运行一个命令,从一个NNTP服务器读取,并监视网页的变化。 坏消息是,它可以做到这一切,并可以使事情过于复杂的简单任务,如OP解释。 python的好处是你只包含你所需要的东西。 所以下载的时候可能是20MB,你可能只包含2mb的库(这还是很多的)。 我最大的抱怨是,虽然他们包括例子,除了你自己的基本的TCP服务器之外的任何东西。
虽然不是python解决scheme,但是我已经看到node.js最近获得了更多的牵引力。 事实上,我考虑调查它的小项目,但我只是畏惧,当我听到JavaScript的:)
关于这个问题有一本好书:Abe Fettig的“Twisted Network Programming Essentials”。 这些例子显示了如何编写非常Python的代码,对我个人而言,不要以我臃肿的框架为基础。 看看书中的解决scheme,如果不干净,那么我不知道干净的手段。
我唯一的谜就是和其他框架一样,比如Ruby。 我担心,它会扩大吗? 我不愿意提交一个客户端到一个将有可伸缩性问题的框架。
Whizzer是一个使用pyev的小型asynchronous套接字框架。 它非常快,主要是因为pyev。 它试图提供一个类似的界面,只是稍微改变一下而已。
也尝试无刷新 。 这是基于协同的(所以它类似于Concurrence,Eventlet和gevent)。 它实现了对socket.socket,socket.gethostbyname(等),ssl.SSLSocket,time.sleep和select.select的embedded式非阻塞replace。 它很快。 它需要Stackless Python和libevent。 它包含用C(Pyrex / Cython)编写的强制性Python扩展。
我确认了syncless的好处 。 它可以使用libev(libevent的更新,更清洁和更好的性能版本)。 前些时候,它没有像自由派那样有足够的支持,但现在发展进程进一步发展,非常有用。
如果你只是想要一个简单的,轻量级的HTTP请求库,那么我觉得Unirest真的很好
欢迎您来看看PyWorks,它采用了一种完全不同的方法。 它允许对象实例在自己的线程中运行,并对该对象进行函数调用asynchronous。
让一个类inheritanceTask而不是Object,它是asynchronous的,所有的方法调用都是代理。 返回值(如果你需要的话)是未来的代理。
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