gevent.hub -事件环路和集线器#

中心是一个特殊的greenlet,自动创建来运行事件循环。

当前集线器可以使用 get_hub .

get_hub()[源代码]#

返回当前线程的集线器。

如果当前线程中不存在集线器,则会创建由返回的类型的新集线器。 get_hub_class() .

自 1.3b1 版本弃用: 这个 *args**kwargs 参数已弃用。它们只在创建集线器时使用,因此是非确定性的——以确保它们被使用, all 打电话的人必须通过电话,否则他们就得按顺序办事。使用 set_hub 相反。

在 1.5a3 版本发生变更: 这个 args关键字参数 现在完全忽略了参数。

在 23.7.0 版本发生变更: 长期不受欢迎的 argskwargs 不再接受参数。

class Hub(loop=None, default=None)[源代码]#

基类:WaitOperationsGreenlet

运行事件循环的greenlet。

它是由自动创建的 get_hub() .

切换

每次切换此greenlet(即事件循环)时 to ,如果当前的greenlet switch_out 方法,将调用它。这允许greenlet在获得控制权之前采取一些清理措施。此方法不应调用任何gevent阻塞函数。

wait(watcher)#

等到 观察者 (不得启动)准备就绪。

在这段时间内,当前的绿let将不在计划范围内。

cancel_wait(watcher, error, close_watcher=False)#

取消正在进行的呼叫 wait() 通过扔给 错误 在等待的绿叶树里。

在 1.3a1 版本发生变更: 增加了 close_watcher 参数。如果为true,则在引发异常后将关闭观察程序。然后应该丢弃观察者。关闭观察程序对于释放本机资源很重要。

在 1.3a2 版本发生变更: 允许 观察者 成为 None . 在这种情况下不采取任何行动。

loop#
the event loop object (`ILoop`) associated with this hub and thus
this native thread.
destroy(destroy_loop=None)[源代码]#

摧毁这个中心并清理它的资源。

如果手动创建集线器,或者从多个本机线程使用集线器或gevent阻塞API,则 应该 在释放中心对象引用之前调用此方法。理想情况下,应该从运行集线器的同一个线程调用它,但是可以在该线程退出后从其他线程调用它。

一旦完成,就不可能继续运行集线器。尝试将阻塞的gevent API与来自本机线程并绑定到此集线器的预先存在的对象一起使用将失败。

在 20.5.1 版本发生变更: 尝试确保此中心引用的Python堆栈帧和greenlet被清除。这保证了在这之后再次切换到集线器是不安全的。(它从来都不安全,但更不安全。)

请注意,只有当集线器在运行它的同一线程中被破坏时,这才有效。如果集线器在 fork() ,例如,预计会有一些垃圾泄漏。

exception_stream()[源代码]#

将写入异常的流。默认为 sys.stderr 除非指定。指定false(None)值将禁用打印异常。

在 1.2a1 版本加入.

handle_error(context, type, value, tb)[源代码]#

发生错误时由事件循环调用。默认操作是将异常打印到 exception stream .

论点 typevaluetb 返回的标准元组是 sys.exc_info() . (请注意,当调用此函数时,调用可能不安全 sys.exc_info()

错误是 not errors 未打印。

错误是 system errors 被传递给 handle_system_error() 打印后。

应用程序可以在中心实例上设置具有相同签名的属性,以覆盖此类提供的错误处理。这是一种高级用法,需要非常小心。这个函数 不能 提出任何例外。

参数:

context -- 如果这是 None ,表示通常会导致退出循环并被抛出到父greenlet的系统错误。

handle_system_error(type, value, tb=None)[源代码]#

从调用 handle_error 当异常类型确定为 system error .

系统错误导致在主greenlet(此集线器的父级)中引发异常。

在 20.5.1 版本发生变更: 允许将回溯传递到主greenlet中,以便与异常关联。

join(timeout=None)[源代码]#

等待事件循环完成。仅当不再有生成的greenlet、已启动的服务器、活动超时或观察程序时退出。

小心

这不会清除与中心关联的所有资源。为此,你看 destroy() .

参数:

timeout (float) -- 如果 超时 ,等待时间不超过指定的秒数。

返回:

True 如果此方法返回是因为循环已完成执行。或者 False 如果超时过期。

run()[源代码]#

运行循环的入口点。此方法在安排集线器greenlet时自动调用;不要直接调用它。

抛出:

gevent.exceptions.LoopExit -- 如果循环结束运行。这意味着没有其他预定的greenlet,也没有活动的观察者或服务器。在某些情况下,这表示编程错误。

NOT_ERROR = (<class 'greenlet.GreenletExit'>, <class 'SystemExit'>)#

这些类的实例不会被视为错误,并且在事件循环引发时不会被记录/打印。

SYSTEM_ERROR = (<class 'KeyboardInterrupt'>, <class 'SystemExit'>, <class 'SystemError'>)#

如果这些类的实例被提升到事件循环中,它们将被传播到主greenlet(在那里它们通常被python本身捕获)。

property main_hub#

这是主螺纹的轮毂吗?

在 1.3b1 版本加入.

name = ''#

给出此集线器名称的字符串。用于将集线器与特定线程关联。作为默认报告的一部分打印。

在 1.3b1 版本加入.

property resolver#

套接字函数将使用的DNS解析程序。

property threadpool#

与此集线器关联的线程池。

通常这是一个 gevent.threadpool.ThreadPool 但是你 can customize that .

使用此对象在不同的线程中调度阻塞(非合作)操作,以防止它们停止事件循环。

threadpool_size = 10#

我们的螺纹工具的尺寸。为此使用子类,或者在创建集线器后立即更改它。

事件循环#

当前事件循环可通过 get_hub().loop . 循环的所有实现都提供一个公共的最小接口。

interface ILoop[源代码]#

所有事件循环都需要公共接口。

小心

这是一个内部的低级接口。它可能在GEvent的次要版本之间发生变化。

观察者

创建事件循环观察程序的方法有 iotimersignalidlepreparecheckforkasync_childstat . 这些都返回各种类型的 IWatcher .

所有这些方法都有一个或两个公共参数。 ref 是一个布尔值,指示是否允许事件循环退出,即使此观察程序仍然启动。 优先 事件循环是否特定。

default#

指示这是否是默认循环的布尔值(必需?真的)

approx_timer_resolution#

给出(近似)计时器最小分辨率的浮点秒数(因此也就是休眠可以休眠的最小值)。在libuv上,这是由库修复的,但在libev上,这只是一个猜测,实际值取决于系统。(必填?真的)

run(nowait=False, once=False)#

运行事件循环。

这通常由集线器greenlet自动调用,但在特殊情况下(集线器是 not 运行)您可以使用它来控制事件循环的运行方式(例如,将其与另一个事件循环集成)。

now()#

now()->浮动

返回循环当前时间的概念。

这不一定与 time.time() (起点可能不同),但必须用分数秒表示(相同 单位 被使用 time.time()

update_now()#

更新循环当前时间的概念。

在 1.3 版本加入: 在过去,这是可用的 update . 此别名仍可用,但将来将删除。

destroy()#

清除此循环使用的资源。

如果创建循环(尤其是非默认循环),则 应该 循环完成后调用此方法。

小心

作为实现说明,libev c循环实现有一个终结器 (__del__ )这会破坏对象,但libuv和libev cffi实现不会。C的实施可能会改变。

io(fd, events, ref=True, priority=None)#

为给定的创建并返回新的IO观察程序 fd .

事件 是指定要监视哪些事件的位掩码。1表示读,2表示写。

closing_fd(fd)#

通知循环文件描述符 fd 即将关闭。

循环可以选择将事件发送给fd的任何活动IO观察者。libev这样做是为了关闭活跃的观察者。

返回:

一个布尔值,如果活动IO观察程序排队等待运行,则为真。关闭FD应该推迟到下次运行带有回调的eventloop。

timer(after, repeat=0.0, ref=True, priority=None)#

创建并返回在 之后 秒。

如果 重复 如果给定,计时器将继续激发 重复 秒。

signal(signum, ref=True, priority=None)#

为信号创建并返回信号监视程序 符号 ,中定义的常量之一 signal .

这是特定于平台和事件循环的。

idle(ref=True, priority=None)#

创建并返回在事件循环空闲时激发的观察程序。

prepare(ref=True, priority=None)#

创建并返回在事件循环轮询IO之前激发的观察程序。

小心

libuv不支持此方法。

check(ref=True, priority=None)#

创建并返回在事件循环轮询IO后激发的观察程序。

fork(ref=True, priority=None)#

创建进程分叉时激发的观察程序。

可用性:Unix。

async_(ref=True, priority=None)#

创建一个观察程序,在触发时触发,可能来自另一个线程。

在 1.3 版本发生变更: 这是以前刚命名的 async ;与python 3.7兼容,其中 async 是一个已重命名的关键字。在旧版本的python上,旧名称仍然存在,但将来将被删除。

child(pid, trace=0, ref=True)#

创建为进程ID为的子级上的事件激发的观察程序 pid .

这是平台特定的,在Windows上不可用。

可用性:Unix。

stat(path, interval=0.0, ref=True, priority=None)#

创建监视文件系统项的监视程序 path .

如果操作系统不支持来自文件系统的事件通知,则轮询 间隔 秒。

run_callback(func, *args)#

运行 func 通过它 args 在下一个时机。

下一个合适的时刻可以是事件循环的下一次迭代、当前迭代或将来的某个其他时间。

返回一个 ICallback 对象。有关重要警告,请参阅该文档。

参见

asyncio.loop.call_soon() 这个 asyncio 等价物。

run_callback_threadsafe(func, *args)#

喜欢 run_callback() ,但供在以下位置使用 外面 运行此循环的线程。

这不仅安排了 func 运行时,它还会使循环注意到 func 已经被调度(例如,它导致循环被唤醒)。

在 21.1.0 版本加入.

参见

asyncio.loop.call_soon_threadsafe() 这个 asyncio 等价物。

interface IWatcher[源代码]#

事件循环观察程序。

这些对象调用 回调 函数,当事件循环检测到事件已发生时。

重要

must 调用 close() 完成此对象以避免本机资源泄漏时。

start(callback, *args, **kwargs)#

让事件循环开始监视此事件。

当检测到事件时, 回调 将与呼叫 args .

小心

并非所有观察者都接受 **kwargs 和一些观察者为某些关键字参数定义特殊含义。

stop()#

让事件循环停止监视此事件。

以后你可以打电话 start() 再次开始观看。

close()#

处置与观察程序关联的任何本机资源。

如果我们是活跃的,停下来。

调用close后尝试对此对象进行操作是未定义的。调用此方法后,应释放对它的任何引用。

interface ICallback[源代码]#

表示将在将来某个时间运行的函数。

回调函数在集线器中运行,因此它们不能使用gevent的阻塞API;它们引发的任何异常都不能被捕获。

pending#

此回调已经运行了吗?(必填?假)

stop()#

如果该对象仍然 pending ,使它不再是 pending ;该函数将不会运行。

close()#

的别名 stop

公用事业#

class Waiter(hub=None)[源代码]#

基类:object

Greenlets的低级通信实用程序。

服务员是格林小店的包袱 switch()throw() 使他们更安全的呼叫:

  • 只有等待的greenlet正在执行时才会发生切换。 get() 目前的方法;

  • 在greenlet中出现的任何错误都在内部处理 switch()throw()

  • 如果 switch()/throw() 在接收器呼叫之前呼叫 get() 然后 Waiter 将存储值/异常。以下内容 get() 将返回值/引发异常。

这个 switch()throw() 方法只能从 Hub 格林莱特。这个 get() 方法必须从greenlet调用,而不是 Hub .

>>> from gevent.hub import Waiter
>>> from gevent import get_hub
>>> result = Waiter()
>>> timer = get_hub().loop.timer(0.1)
>>> timer.start(result.switch, 'hello from Waiter')
>>> result.get() # blocks for 0.1 seconds
'hello from Waiter'
>>> timer.close()

如果在Greenlet有机会呼叫之前调用了switch get() 然后 Waiter 存储值。

>>> from gevent.time import sleep
>>> result = Waiter()
>>> timer = get_hub().loop.timer(0.1)
>>> timer.start(result.switch, 'hi from Waiter')
>>> sleep(0.2)
>>> result.get() # returns immediately without blocking
'hi from Waiter'
>>> timer.close()

警告

这是一种在菜鸟之间交流的有限而危险的方式。如果使用不当,它很容易让一个绿色小菜永远不被安排。考虑使用更安全的类,如 gevent.event.Eventgevent.event.AsyncResultgevent.queue.Queue .

get()[源代码]#

如果存储了值/异常,则返回/引发它。否则,直到调用switch()或throw()。

ready()[源代码]#

仅当且仅当它包含值或异常时返回true

successful()[源代码]#

如果且仅当它已准备好并保持值时返回true

switch(value)[源代码]#

如果有的话,换成绿色的。否则存储 价值 .

在 1.3b1 版本发生变更: 这个 价值 不再是可选的。

throw(*throw_args)[源代码]#

切换到greenlet,但有例外。如果没有绿叶树,就存储例外。

property exc_info#

保留传递给的异常信息 throw() 如果 throw() 被呼叫。否则 None .

例外情况#

class LoopExit[源代码]#

基类:Exception

当集线器完成运行时引发异常 (gevent.hub.Hub.run 会回来的)。

在正常的应用程序中,不会显式地抛出或捕获。诸如 gevent.hub.Hub.join()gevent.joinall() 可能会捕获它,但用户代码通常不应捕获它。

小心

应用程序编程中的错误也可能导致引发此异常。一些例子包括(但不限于):

  • 格林莱特在锁上死锁;

  • 使用来自不同线程的具有本机线程关联性的套接字或其他gevent对象

property hub#

引发错误的(可选)集线器。

在 20.12.0 版本加入.

以下例外情况 不是 期望被抛出和 不是 意味着被捕获;如果它们被提升为用户代码,则通常是一个严重的编程错误,或者是gevent、greenlet或其事件循环实现中的一个bug。此处仅作文档用途。

class ConcurrentObjectUseError[源代码]#

基类:AssertionError

当一个对象被两个greenlet单独使用(等待)时引发,这意味着该对象在第一个greenlet仍处于阻塞状态时由一个greenlet进入阻塞状态,然后由另一个greenlet进入阻塞状态。

这通常是编程错误。

class BlockingSwitchOutError[源代码]#

基类:AssertionError

从低级事件循环回调调用gevent同步函数时引发。

这通常是编程错误。

class InvalidSwitchError[源代码]#

基类:AssertionError

当事件循环意外地将控件返回到greenlet时引发。

这通常是gevent、greenlet或事件循环中的错误。