Gevent 1.1的新功能#

详细信息更改内容可在 1.1版的更改 . 本文档总结了自 gevent 1.0.2 .

更广泛的平台支持#

gevent 1.1在cpython上支持python 2.6、2.7、3.3和3.4 (python.org) 翻译。它还支持 PyPy 2.6.1及以上(推荐PYPY 4.0.1或更高版本);不支持PYPY3。

添加了对python 3的支持后,对python 2.5的支持被删除。1.0.x行中的任何进一步版本都将维护对python 2.5的支持。

备注

版本1.1.x将是支持python 2.6的最后一系列gevent版本。下一个主要版本将只支持Python2.7及更高版本。

python 3.5具有初步的支持,这意味着gevent通常以与python 3.4相同的支持级别运行和运行,但是3.5中引入的新特性和API可能没有得到适当的支持(例如, DevpollSelector )而且由于最近python 3.5的到来,它所接受的测试级别更低。

为了便于在Windows和OS X上安装,除了源代码外,gevent 1.1还作为预编译的二进制轮子分发。

Pypy笔记#

Pypy已经在2.6.1到4.0.0和4.0.1版本的OS X和64位Linux上进行了测试,并在4.0.1版本的Raspbian上的32位ARM上进行了测试。

备注

在Windows上不支持Pypy。(Gevent的CFFI后端在Windows上不可用。)

  • 4.0.1或更高版本为 强烈推荐 因为它相对于早期版本有大量的错误修复。

  • 2.6.1或更高版本为 必修的 以便正确处理信号。2.6.1之前及其包含 cffi 1.3.0 ,在阻塞操作期间,信号可能传递不正确或无法传递。(PYPY 2.5.0包括CFFI 0.8.6,而2.6.0包含1.1.0;在 1.2.0 它本身并不直接出现在任何Pypy版本中。)cffi 1.3.0还允许在cpython上使用cffi后端。

  • 对于Pypy的新版本,整体性能似乎是可以接受的。与gevent一起发布的基准测试在pypy上的性能通常与cpython相同或更好,至少在某些平台上是这样。Pypy下已知或预期(相对)较慢的事情包括 c-ares resolverSemaphore . 这些问题是否取决于每个应用程序的工作负载 (pull request #708 提到一些具体的基准 Semaphore

小心

这个 c-ares 解析器在PYPY下被认为是高度实验性的,不推荐用于生产。通过至少4.0.1发布的pypy版本 a bug 当子类化在Cython中实现的对象时,这会导致内存泄漏,C-ARES解析器也是如此。此外,感谢像 issue #704 我们知道pypy垃圾收集器会与cython编译的代码发生严重的交互,从而导致崩溃。虽然对战神分解器的预期用途已经进行了松散的审计,但没有作出任何保证。

备注

已知Linux上的pypy 4.0.x 很少地 (每24小时一次)在运行重负载、重网络化的gevent程序(即使没有 c-ares )。确切原因尚不清楚,正在追踪 issue #677 .

操作系统#

gevent在mac os x、ubuntu linux和windows上定期构建和测试,包括32位和64位配置。这三个平台主要在x86/AMD64体系结构上进行测试,而Linux也偶尔在ARM上的Raspian上进行测试。

一般来说,gevent应该在python和 libev support . 然而,一些不太常用的平台可能需要调整gevent源代码或用户环境来编译(例如, SmartOS )。此外,由于时间等方面的差异,一些平台可能无法完全通过Gevent的广泛测试套件(例如, OpenBSD

漏洞修补#

从1.0.2开始,gevent 1.1包含了来自近20个贡献者的600多个提交。超过200个问题被关闭,超过50个请求被合并。

改进的子流程支持#

在gevent 1.0中,支持和猴修补 subprocess 模块已添加。默认情况下,修补此模块的monkey已关闭。

在1.1中,猴子修补 subprocess 由于下游库在处理子进程和需求方面的改进,默认情况下启用,尤其是 gunicorn .

  • gevent.os.fork() ,默认情况下是monkey补丁的(应该用于派生一个gevent-aware进程,该进程希望在子进程中使用gevent),已经得到改进并与 gevent.os.waitpid() (再次默认修补猴子)和 gevent.signal.signal() (这只猴子只为 signal.SIGCHLD 案例)。后两个补丁在1.1中是新的。

  • 在gevent 1.0中,使用libev儿童观察程序(内部由 gevent.subprocess )有用户提供的比赛条件 SIGCHLD 处理程序,导致许多类型的不可预测的损坏。上面描述的两个新API旨在纠正这一问题。

  • 即使在多线程程序中(在Windows上除外),也将调用fork watcher。

  • 默认的threadpool和threaded resolver在子进程中工作。

  • 如果 gevent.subprocess.Popen 无法启动孩子。

此外,简单使用 multiprocessing.Process 现在可以在猴子补丁系统中使用,至少在POSIX平台上是如此。

小心

使用 multiprocessing.Queue 什么时候? thread 被猴子修补过会导致吊死 Queue 内部使用堵管和线程。出于同样的原因, concurrent.futures.ProcessPoolExecutor ,内部使用 Queue ,将挂起。

小心

不可能使用 gevent.subprocess 来自本机线程。见 gevent.subprocess 有关详细信息。

备注

如果 SIGCHLD 信号处理,猴子补丁(或直接使用)两者都很重要 ossignal ;这是默认的 patch_all() . 不这样做会导致 SIGCHLD 信号丢失。

小技巧

所有这些都需要分叉一个子进程。如果一个孩子不立即使用gevent、greenlets和libev,那么使用这种子进程可能会产生一些意想不到的后果。 exec 一个新的二进制文件。在使用此功能之前,尤其是在程序生命周期的后期,一定要了解这些后果。对于子进程某些用途的更健壮的解决方案,请考虑 gipc .

猴子修补#

猴子补丁更强大,特别是如果标准库 threadinglogging 在应用修补程序之前已导入模块。此外,现在有支持的方法来确定某些东西是否被猴子修补过。

API添加#

许多API在此版本中提供了稍微扩展的功能。在整个文档中查找“在1.1版中更改”或“在1.1版中添加”以了解详细信息。亮点包括:

  • Gevent友好版 select.poll (在实现它的平台上)。

  • FileObjectPosix 使用 io 在python 2和python 3上打包,提高了其功能性、正确性和性能。(以前,python 2实现使用了未记录的类 socket._fileobject

  • 如果过度释放,锁会引发与标准库锁相同的错误。同样,如果SSL套接字在关闭后被读取或写入,那么它们会产生与捆绑的对应套接字相同的错误。

  • ThreadPool.apply 现在可以递归使用。

  • 各种池对象 (GroupPoolThreadPool )支持相同的改进API: imapimap_unordered 接受多个iterables, apply 引发由目标可调用文件等引发的任何异常。

  • 杀了一个格林莱特 gevent.kill()Greenlet.kill )在它实际启动并切换到now之前,将阻止greenlet运行,而不是在稍后切换到时引发异常。尝试生成一个带有无效目标的greenlet,现在会立即生成一个有用的 TypeError 而不是产生一个绿叶小菜,它会(通常)立即死亡第一次被切换到。

  • 几乎任何一个gevent引发了从一个greenlet到另一个greenlet的异常(例如, Greenlet.get )保留并提出了原始的回溯。

  • 已清除了各种日志记录/调试输出。

  • 在中找到的wsgi服务器 gevent.pywsgi 对于客户端或wsgi应用程序中的错误更为可靠,修复了几个挂起或HTTP协议冲突。它还支持新的功能,如可配置的错误处理和日志记录。

  • 文件已经扩展和澄清。

库更新#

与gevent捆绑在一起的两个C库已经更新。libev已从4.19更新为4.20 (libev release notes )c-ares从1.9.1更新到1.10.0 (c-ares release notes

小心

C战神 configure 脚本现在 much 对编译环境变量(如 $CFLAGS$LDFLAGS . 例如, $CFLAGS 不再允许包含 -I 指令;相反,这些必须放在 $CPPFLAGS . 这是在POSIX平台上从头编译时出现以下错误的一个常见原因:

Running '(cd  "/tmp/easy_install-NT921u/gevent-1.1b2/c-ares"  && if [ -e ares_build.h ]; then cp ares_build.h ares_build.h.orig; fi   && /bin/sh ./configure CONFIG_COMMANDS= CONFIG_FILES=   && cp ares_config.h ares_build.h "$OLDPWD"   && mv ares_build.h.orig ares_build.h) > configure-output.txt' in /tmp/easy_install-NT921u/gevent-1.1b2/build/temp.linux-x86_64-2.7/c-ares
configure: error: Can not continue. Fix errors mentioned immediately above this line.

兼容性#

此版本旨在与1.0.x兼容,对客户端源代码的更改最少或不更改。但是,需要注意的一些更改可能会影响某些应用程序。这些变化大部分是由于python 3和pypy平台支持的增加以及未记录或非标准行为的减少。

  • gevent.baseserver.BaseServer 确切地 closes its sockets .

    一旦请求完成(请求处理程序返回),则 BaseServer 及其子类,包括 gevent.server.StreamServergevent.pywsgi.WSGIServer 关闭客户端套接字。

    在gevent 1.0中,客户机套接字留给了垃圾收集器(这是未记录的)。在典型情况下,由于cpython的引用计数垃圾收集器,一旦请求处理程序返回,套接字仍将关闭。但这意味着一个引用循环可能会让一个套接字悬空打开一段不确定的时间,并且引用泄漏将导致它永远不会被关闭。它还意味着python 3将生成resourcewarnings和pypypy(与cpython不同, does not use a reference-counted GC )只能关闭(并冲洗!)将来任意时间的套接字。

    如果您的应用程序依赖于请求处理程序返回时未关闭的套接字(例如,您生成了一个继续使用套接字的greenlet),则需要阻止请求处理程序返回(例如, join 绿叶树)。如果由于某些原因不可能,您可以将服务器子类化,以防止它关闭套接字,此时关闭和刷新套接字的责任现在由您自己承担; but 前一种方法是非常可取的,因此将来可能不支持对服务器进行子类化。

  • gevent.pywsgi.WSGIServer 确保应用程序设置的标题(名称和值)和状态行可以用ISO-8859-1(拉丁文-1)字符集编码,并且属于 本机字符串类型 .

    在gevent 1.0下,非``字节``头(即, unicode ,因为gevent 1.0只在python 2上运行,尽管对象 int 也允许)根据当前默认的python编码进行编码。在某些情况下,这可能允许在头文件中发送非拉丁-1字符,但这违反了HTTP规范,并且收件人对这些字符的解释未知。在其他情况下,gevent可能会发送格式错误的部分HTTP响应。现在,A UnicodeError 将积极提出。

    大多数应用程序都遵循WSGI PEP, PEP 3333 ,不需要进行任何更改。见 issue #614 更多讨论。

  • 在python 2下,以前未记录的 timeout 参数到 Popen.wait (一个gevent扩展)现在抛出一个异常,就像python 3中相同stdlib方法的文档化参数一样。

  • 在python 3下,添加了几个标准库方法 timeout 参数。这些通常默认为-1表示“无超时”,而gevent使用默认值 None 意思是相同的,可能会在可移植代码中导致巨大的混乱和错误。在gevent中,使用负值总是定义不清,很难解释。因为这两件事,截至本次发布,负面 timeout 应将值视为已弃用(除非另有说明)。当前定义不明确的行为得到了维护,但将来的版本可能会选择将其视为 None 或引发错误。由于性能原因,没有为此更改发出运行时警告。

  • 以前未记录的类 gevent.fileobject.SocketAdapter 已经被移除,内部 gevent._util 模块和一些内部实现模块在1.1的早期预发行版中找到。