gevent.monkey
--使标准库合作#
实现标准库的协作化。
本模块的主要目的是仔细修补标准库的部分,使其具有与原始库相同的、对gevent友好的功能(至少尽可能接近)。
它的主要接口是 patch_all()
函数,执行所有可用的修补程序。它接受参数来限制对某些模块的修补,但大多数程序 应该 使用默认值,因为它们接收最广泛的测试,并且一些monkey补丁依赖于其他补丁。
修补 应该尽早完成 在程序的生命周期中。例如,主模块 __main__
或者是第一次导入)应该以该代码开头,最好是在任何其他导入之前:
from gevent import monkey
monkey.patch_all()
上面的推论是修补 应该在主线程上完成 和 should be done while the program is single-threaded .
小技巧
一些框架,如Gunicorn,为您处理猴子修补。检查他们的文档以确定。
警告
太迟的修补可能导致不可靠的行为(例如,一些模块可能仍然使用阻塞套接字)甚至错误。
小技巧
请务必阅读每个补丁功能的文档以检查已知的不兼容性。
查询#
有时,了解对象是否被猴修补是很有帮助的,在高级情况下甚至可以访问原始的标准库函数。本模块为此目的提供功能。
插件和事件#
从GEvent 1.3开始,在猴子修补过程中会发出事件。这些事件首先传递给 gevent.events
订户,然后到 setuptools entry points .
定义了以下事件。它们大致按呼叫的顺序列出 patch_all()
将发射它们。
每个事件类记录相应的设置工具入口点名称。将使用单个参数调用入口点,该参数是发送给订阅服务器的类的同一实例。
您可以订阅事件以监视猴子修补过程并对其进行操作,例如通过提升 gevent.events.DoNotPatch
.
您还可以订阅这些事件,以提供超出gevent分发范围的额外补丁,无论是用于额外的标准库模块,还是用于第三方软件包。此修补的建议时间在订阅服务器中 gevent.events.GeventDidPatchBuiltinModulesEvent
. 例如,自动修补 psycopg2 使用 psycogreen 当呼叫到 patch_all()
是的,你可以这样写代码:
# mypackage.py
def patch_psycopg(event):
from psycogreen.gevent import patch_psycopg
patch_psycopg()
在你 setup.py
您可以这样注册:
from setuptools import setup
setup(
...
entry_points={
'gevent.plugins.monkey.did_patch_builtins': [
'psycopg2 = mypackage:patch_psycopg',
],
},
...
)
对于更复杂的补丁,gevent提供了一个助手方法,您可以调用该方法用自己模块的属性替换模块的属性。此函数还负责发出适当的事件。
用作模块#
有时运行现有的python脚本或模块是有用的,这些脚本或模块不是在gevent下构建为可识别gevent的。为此,此模块可以作为主模块运行,传递脚本及其参数。有关详细信息,请参见 main()
功能。
在 1.3b1 版本发生变更: 增加了对插件的支持,并开始发出will/did补丁事件。
- get_original(mod_name, item_name)[源代码]#
从模块中检索原始对象。
如果对象尚未修补,则仍将检索该对象。
- 参数:
mod_name (str) -- 标准库模块的名称,例如,
'socket'
. 也可以是一个标准库模块的序列,提供其他名称供尝试,例如。,('thread', '_thread')
;第一个可导入模块将提供所有 item_name 项目。item_name -- 一个字符串或字符串序列,用于命名模块上的属性。
mod_name
返回。
- 返回:
如果为指定了字符串,则返回原始值
item_name
如果传递了序列,则为原始值序列。
- main()[源代码]#
monkey-monkey修补标准模块以使用gevent。
用途:
python -m gevent.monkey [MONKEY OPTIONS] [--module] (script|module) [SCRIPT OPTIONS]
如果没有MONKEY选项,MONKEY会像调用
patch_all()
. 您可以排除具有--no-<module>的模块,例如--no thread。您可以指定要用--<module>进行修补的模块,例如--socket。在后一种情况下,只修补命令行中指定的模块。默认行为是执行作为参数传递的脚本。如果要运行模块,请传递
--module
在模块名之前的参数。在 1.3b1 版本发生变更: 这个 脚本 参数现在可以是任何可以传递给
runpy.run_path
, just like the interpreter itself does, for example a package directory containing ``_ _主“y”。以前它必须是.py源文件的路径。在 1.5 版本发生变更: 这个
--module
已添加选项。猴子选项:
--verbose --[no-]socket, --[no-]dns, --[no-]time, --[no-]select, --[no-]thread, --[no-]os, --[no-]ssl, --[no-]subprocess, --[no-]sys, --[no-]builtins, --[no-]signal, --[no-]queue, --[no-]contextvars
- patch_all(socket=True, dns=True, time=True, select=True, thread=True, os=True, ssl=True, subprocess=True, sys=False, aggressive=True, Event=True, builtins=True, signal=True, queue=True, contextvars=True, **kwargs)[源代码]#
执行所有默认的monkey补丁(调用此模块中的其他所有适用函数)。
- 返回:
如果未取消修补所有模块,则为真值;如果取消修补,则为假值。
在 1.1 版本发生变更: 发行A
warning
如果用不同的参数多次调用此函数。第二次和后续调用将只添加更多的修补程序,它们无法通过将参数设置为False
.在 1.1 版本发生变更: 发行A
warning
如果使用os=False
和signal=True
. 这将导致不调用SIGCHLD处理程序。这可能是将来的错误。在 1.3a2 版本发生变更:
Event
默认为true。在 1.3b1 版本发生变更: 定义了返回值。
在 1.3b1 版本发生变更: 添加
**kwargs
为了事件订阅者的利益。警告:gevent将来可能会添加和解释其他参数,因此建议使用前缀来解释Kwarg值,例如,插件将其解释为patch_all(mylib_futures=True)
.在 1.3.5 版本发生变更: 添加 队列 ,默认为true,对于python 3.7。
在 1.5 版本发生变更: 移除
httplib
争论。以前,设置它会引发一个ValueError
.在 1.5a3 版本发生变更: 添加
contextvars
争论。在 1.5 版本发生变更: 更好地处理多次修补。
- patch_builtins()[源代码]#
制造内置的
__import__()
功能 greenlet safe 在python 2下。备注
这在Python3下不起作用,因为它是不必要的。python 3的特点是改进了每个模块的导入锁,而不是全局的。
自 23.7.0 版本弃用: 在任何受支持的平台上不执行任何操作。
- patch_dns()[源代码]#
替换 DNS functions 在里面
socket
与合作版本。只有当
patch_socket()
已被调用,并在被请求时由该方法自动完成。
- patch_module(target_module, source_module, items=None)[源代码]#
替换中的属性 target_module 在中具有相同名称的属性 source_module .
这个 source_module 可以提供一些属性来定制流程:
__implements__
是要复制的属性名称列表;如果不存在,则 项目 关键字参数是必需的。__implements__
必须只包含标准库模块中的名称。_gevent_will_monkey_patch(target_module, items, warn, **kwargs)
_gevent_did_monkey_patch(target_module, items, warn, **kwargs)
这两个功能在 source_module 被称为 if 它们分别存在于复制属性之前和之后。“will”功能可以修改 项目 .价值 warn 是一个应使用单个字符串参数调用的函数,以向用户发出警告。如果“will”函数上升gevent.events.DoNotPatch
,不进行修补。在任何事件订阅服务器或插件之前调用这些函数。
- 参数:
items (list) -- 要替换的属性名称列表。如果没有给出,将从 source_module
__implements__
属性。- 返回:
如果完成了修补,则为真值;如果取消了修补,则为假值。
在 1.3b1 版本加入.
- patch_os()[源代码]#
替换
os.fork()
具有gevent.fork()
,在posix上,os.waitpid()
具有gevent.os.waitpid()
(如果环境变量GEVENT_NOWAITPID
未定义)。如果叉子不可用,则不执行任何操作。小心
此方法必须与
patch_signal()
拥有适当的SIGCHLD
处理,从而纠正waitpid
.patch_all()
默认情况下调用两个。小心
为了
SIGCHLD
要正确处理,必须运行事件循环。确保这一点的最简单方法是patch_all()
.
- patch_queue()[源代码]#
在python 3.7及更高版本上,替换
queue.SimpleQueue
(在C中实现)及其对应的Python。在 1.3.5 版本加入.
- patch_select(aggressive=True)[源代码]#
替换
select.select()
具有gevent.select.select()
和select.poll()
具有gevent.select.poll
(如有)。如果
aggressive
为真(默认值),同时从select
.select.devpoll()
(python 3.5+)
- patch_signal()[源代码]#
使
signal.signal()
函数与monkey-patched os
.小心
此方法必须与
patch_os()
拥有适当的SIGCHLD
处理。patch_all()
默认情况下调用两个。小心
为了正确
SIGCHLD
处理时,必须屈服于事件循环。使用patch_all()
这是确保这一点的最简单方法。
- patch_ssl() None [源代码]#
替换
ssl.SSLSocket
对象和套接字包装函数ssl
与合作版本。只有当
patch_socket()
已被调用。
- patch_subprocess()[源代码]#
替换
subprocess.call()
,subprocess.check_call()
,subprocess.check_output()
和subprocess.Popen
具有cooperative versions
.备注
在Python3下的Windows上,API支持可能与标准库不完全匹配。
- patch_sys(stdin=True, stdout=True, stderr=True)[源代码]#
补丁系统标准 [进,出,呃] 通过线程池使用合作IO。
这是相对危险的,可能会产生意想不到的后果,例如挂起进程或 misinterpreting control keys 什么时候?
input()
和raw_input()
被使用。patch_all()
做 not 默认情况下调用此函数。这个方法对python 3没有任何作用。python 3解释器希望在关闭时刷新组成stderr/stdout的textiographer对象,但在关闭时使用threadpool会导致挂起。
自 23.7.0 版本弃用: 在任何支持的版本上不执行任何操作。
- patch_thread(threading=True, _threading_local=True, Event=True, logging=True, existing_locks=True) None [源代码]#
替换标准
thread
使其基于greenlet的模块。- 参数:
_threading_local (bool) -- 当为真(默认值)时,还将修补
_threading_local.local
.logging (bool) -- 如果为真(默认值),则在配置了日志记录模块的情况下也会使用补丁锁。
existing_locks (bool) -- 如果为true(默认值),并且进程仍然是单线程的,请确保
threading.RLock
(在python 3下,importlib._bootstrap._ModuleLock
)当前锁定的实例可以正确解锁。 重要的 :这是尽最大努力的尝试,在某些实现中,可能不会检测到所有锁。在启动过程中非常早地进行monkey-patch是很重要的。不建议将其设置为False,尤其是在python2上。
小心
猴子修补
thread
并使用multiprocessing.Queue
或concurrent.futures.ProcessPoolExecutor
(使用Queue
)将挂起进程。在某些平台上,使用此函数和使用子解释器(以及高级C级API)和线程进行Money修补可能会不稳定。
在 1.1b1 版本发生变更: 添加 登录中 和 existing_locks 参数。
在 1.3a2 版本发生变更:
Event
默认为true。
- patch_time()[源代码]#
替换
time.sleep()
具有gevent.sleep()
.