Greenlet对象

gevent.Greenlet 是一个轻量级的协同调度执行单元。它是一个更强大的版本 greenlet.greenlet . 有关一般信息,请参见 轻量级伪线程 .

您可以随时使用 gevent.getcurrent() .

启动Greenlets

要启动新的greenlet,请将目标函数及其参数传递给 Greenlet 构造函数和调用 Greenlet.start()

>>> from gevent import Greenlet
>>> def myfunction(arg1, arg2, kwarg1=None):
...    pass
>>> g = Greenlet(myfunction, 'arg1', 'arg2', kwarg1=1)
>>> g.start()

或者使用classmethod Greenlet.spawn() 这是一个执行相同操作的快捷方式:

>>> g = Greenlet.spawn(myfunction, 'arg1', 'arg2', kwarg1=1)

还有各种各样的产卵助手 gevent ,包括:

等待小绿叶

你可以等待一张绿票以它的 Greenlet.join() 方法。有一些帮助器函数可用于联接多个greenlet或异构对象集合:

停止Greenlets

你可以强行阻止 Greenlet 利用其 Greenlet.kill() 方法。还有一些辅助函数在有限的情况下是有用的(如果您可能有 raw greenlet ):

上下文管理器

21.1.0 新版功能.

Greenlet还充当上下文管理器,因此您可以在一行中组合生成和等待Greenlet完成:

>>> def in_greenlet():
...     print("In the greenlet")
...     return 42
>>> with Greenlet.spawn(in_greenlet) as g:
...     print("In the with suite")
In the with suite
In the greenlet
>>> g.get(block=False)
42

通常情况下,会加入小绿程序以等待其完成,但是如果套件的主体引发异常,则小绿程序将使用该异常终止。

>>> import gevent
>>> try:
...    with Greenlet.spawn(gevent.sleep, 0.1) as g:
...       raise Exception("From with body")
... except Exception:
...     pass
>>> g.dead
True
>>> g.successful()
False
>>> g.get(block=False)
Traceback (most recent call last):
...
Exception: From with body

Greenlet子类

子类A Greenlet ,重写其 _run() 方法和调用 Greenlet.__init__(self) 在子类中 __init__ . 这可以用来覆盖 Greenlet.__str__() 如果 _run 引发异常,它的字符串表示形式将在它生成的回溯之后打印。

class MyNoopGreenlet(Greenlet):

    def __init__(self, seconds):
        Greenlet.__init__(self)
        self.seconds = seconds

    def _run(self):
        gevent.sleep(self.seconds)

    def __str__(self):
        return 'MyNoopGreenlet(%s)' % self.seconds

重要

不应该 尝试重写 run() 方法。

布尔上下文

greenlet对象具有布尔值 (__nonzero____bool__ )如果它是活动的,这是正确的:开始但还没有结束。

可以这样使用:

>>> g = gevent.spawn(...)
>>> while g:
       # do something while g is alive

greenlet的布尔值是对原始值的改进 greenlet's 布尔值。如果greenlet尚未切换到或已经死了,则原始greenlet的布尔值返回false。虽然后者是好的,但前者并不好,因为一个刚刚产生的绿let还没有被切换到,因此会被评估为假。

exception GreenletExit

一个特殊的例外,悄悄地杀死了格林莱特。

当绿叶树长起来的时候 GreenletExit 或者是一个子类,不打印回溯,并考虑使用greenlet successful . 异常实例在下可用 value 属性,就好像它是由greenlet返回的,而不是引发的。

class Greenlet[源代码]
Greenlet.__init__(run=None, *args, **kwargs)[源代码]
参数
  • args -- 传递给 run 功能。

  • kwargs -- 传递给的关键字参数 run 功能。

  • run (callable) -- 要运行的可调用对象。如果没有给出,这个对象 _run 方法将被调用(通常由子类定义)。

在 1.1b1 版更改: 这个 run 构造函数的参数现在被验证为可调用对象。以前,在生成greenlet后传递不可调用的对象将失败。

在 1.3b1 版更改: 这个 GEVENT_TRACK_GREENLET_TREE 配置值可以设置为假值以禁用 spawn_tree_localsspawning_greenletspawning_stack . 在这种情况下,前两个是空的,后一个是空的。

在 1.5 版更改: Greenlet对象现在更加小心地验证 parent gevent真的是一个集线器 TypeError 而不是 AttributeError 后来。

在 20.12.1 版更改: Greenlet对象现在充当上下文管理器。正在退出 with 套件可确保小绿件在以下时间之前完成 joining 小绿灯(阻塞,没有超时)。如果套间的主体引发异常,则greenlet为 killed 使用默认参数,在这种情况下不联接。

属性

Greenlet.exception

保留函数引发的异常实例(如果greenlet已完成但出现错误)。否则 None .

Greenlet.minimal_ident

标识此对象的唯一的小整数。

这和 threading.Thread.ident (和 id )只要这个物体还活着,就没有别的绿叶树 在这个中心 将具有相同的ID,但它可以更有力地保证分配的值是小的和连续的。在这个对象死后的某个时候,该值将可以重用。

要获取所有集线器上唯一的ID,请将其与集线器的 (self.parentminimal_ident .

未定义从运行此greenlet的线程以外的线程访问此属性。

1.3a2 新版功能.

Greenlet.name = <gevent._util.readproperty object>[源代码]
Greenlet.dead

布尔值,表示greenlet已死,不会再次运行。

如果:

  1. 我们从未开始,但 killed 不可能在创建后立即 spawn() )或

  2. 我们开始行动,但在逃跑前被杀;或者

  3. 我们已经运行并终止(通过在已启动函数之外引发异常或到达已启动函数的结尾)。

Greenlet.value

如果greenlet成功完成,则保留函数返回的值。直到那时,或者如果它错误地完成了, None .

小技巧

还记得一个格林莱特因违约而被杀 GreenletExit 被认为已成功完成,并且 GreenletExit 异常将是其值。

Greenlet.spawn_tree_locals

在“产卵树”中,所有小树之间共享的字典,即产卵小树及其所有后代小树。所有主要(根)绿叶树的子代开始自己的产卵树。在这个类的一个实例上为这个属性分配一个新字典,以创建一个新的衍生树(就局部变量而言)。

1.3a2 新版功能.

Greenlet.spawning_greenlet

创建此对象时当前的对greenlet的弱引用。注意, parent 属性始终是中心。

1.3a2 新版功能.

Greenlet.spawning_stack

轻量级 frame -类似于创建此greenlet时捕获堆栈的对象,以及创建生成greenlet时捕获堆栈的对象(如果适用)。这个可以传递给 traceback.print_stack() .

1.3a2 新版功能.

Greenlet.spawning_stack_limit

一个类属性,指定将保留多少级别的生成堆栈。为更高的性能指定较小的数字,生成greenlet,为改进的调试指定较大的值。

1.3a2 新版功能.

方法

classmethod Greenlet.spawn(function, *args, **kwargs) Greenlet[源代码]

创建新的 Greenlet 对象并计划其运行 function(*args, **kwargs) . 这个可以用作 gevent.spawnGreenlet.spawn .

参数传递给 Greenlet.__init__() .

在 1.1b1 版更改: 如果A 功能 如果是不可调用的,则立即引发 TypeError 而不是生成一个将引发未捕获类型错误的greenlet。

Greenlet.ready()[源代码]

仅当greenlet已完成执行时才返回真值。

在 1.1 版更改: 此函数只保证返回true或false 价值观 ,不一定是文字常量 TrueFalse .

Greenlet.successful()[源代码]

如果且仅当greenlet成功完成执行时,即不引发错误,则返回真值。

小技巧

因违约而被杀的格林莱特 GreenletExit 异常被认为是成功的。也就是说, GreenletExit 不视为错误。

注解

此函数只保证返回true或false 价值观 ,不一定是文字常量 TrueFalse .

Greenlet.start()[源代码]

安排greenlet在此循环迭代中运行

Greenlet.start_later(seconds) None[源代码]

安排greenlet在将来的循环迭代中运行 后来

Greenlet.join(timeout=None) None[源代码]

等到绿房子完工或者 超时 到期。返回 None 无论如何。

Greenlet.get(block=True, timeout=None) object[源代码]

返回greenlet返回的结果或重新引发其引发的异常。

如果块是 False ,升高 gevent.Timeout 如果绿叶树还活着。如果块是 True ,取消当前greenlet的计划,直到结果可用或超时结束。在后一种情况下, gevent.Timeout 提高了。

Greenlet.kill(exception=GreenletExit, block=True, timeout=None)[源代码]

提高 exception 在绿地里。

如果 blockTrue (默认情况下),等待greenlet终止或可选超时过期;这可能需要切换greenlet。如果块是 False ,当前的绿色let不是计划外的。

此函数始终返回 None 从不出错。它可以在同一个greenlet对象上被称为multpile times,也可以在一个未开始或死的greenlet上调用。

注解

根据此greenlet正在执行的内容和事件循环的状态,此greenlet恢复执行时可能会立即引发异常,也可能不会立即引发异常。它可能会在随后的绿色电话会议上提出,或者,如果在作出此类电话会议之前退出,则它可能根本不会提出。从1.1开始,如果这个greenlet调用了 sleep(0) ;立即引发异常的示例是,如果此greenlet调用了 sleep(0.1) .

警告

杀小菜时要小心。如果执行的代码不是异常安全的(例如,正确使用 finally )然后意外的异常可能会导致损坏的状态。使用 link()rawlink() (更便宜)可能是清理资源更安全的方法。

另请参阅 gevent.kill()gevent.killall()

参数

exception (type) -- 在greenlet中引发的异常类型。默认值是 GreenletExit ,表示 successful() 完成绿色小菜。

在 0.13.0 版更改: 现在是 True 默认情况下。

在 1.1a2 版更改: 如果这个绿色小菜从来没有换过,杀死它会阻止它 ever 正在切换到。链接 (rawlink() )但仍将被处决。

在 20.12.1 版更改: 如果这张绿票是 ready() ,而不是需要绕过事件循环。

将greenlet的完成链接到可调用文件。

这个 回调 一旦greenlet死了,将用此实例作为参数调用。一个可调用的调用是自己调用的 greenlet.greenletnotGreenlet

喜欢 link() 但是 回调 只有在greenlet成功完成时才会收到通知。

喜欢 link() 但是 回调 只有当greenlet因未处理的异常而死亡时才会通知。

注册可在greenlet完成执行时执行的调用。

这个 回调 将用此实例作为参数调用。

警告

这个 回调 将在中心调用 不能 提出一个例外。

删除由设置的回调 link()rawlink()

Greenlet.__str__()

返回str(self)。

static Greenlet.add_spawn_callback(callback) None[源代码]

设置 回调 在以下情况下调用 Greenlet 对象已启动。

未指定生成回调的调用顺序。多次添加同一个回调不会导致多次调用该回调。

1.4.0 新版功能.

static Greenlet.remove_spawn_callback(callback) None[源代码]

去除 回调 函数添加为 Greenlet.add_spawn_callback() . 如果 回调 已被删除或如果 回调 从未添加。

1.4.0 新版功能.

原始Greenlet方法

成为 greenlet 子类, Greenlet 也有 switch()throw() 方法。但是,这些不应该在应用程序级别使用,因为它们很容易导致永远没有计划的greenlet。喜欢更高级的安全级别,比如 EventQueue ,而不是。

class greenlet.greenlet

从中 Greenlet 下降。

Next page: 实现服务器