【generator101】 – 对比generator和greenlet
admin
2023-07-31 01:50:17
0

前面讲generator是显式的协程的时候缺一个例子,现在补上

def parent_generator():
    print(\'hello\')
    yield from sub_generator()
    print(\'world\')

def sub_generator():
    yield 1

gen = parent_generator()
gen.send(None)
gen.send(None)

这里可以看出parent_generator为了在hello和world之间中断,必须显式的用yield from把控制权从自己手里转交给调用者。如果parent_generator没有使用yield,那么sub_generator里即使有yield也无法使得parent_generator的执行权转交出去。所以从视觉上可以一步了然的指导一个函数中哪些调用是产生了switch的,哪些是肯定顺序执行的。有一点类似Haskell里给所有I/O操作加类型标签的味道。

from greenlet import greenlet

def parent():
    print(\'hello\')
    sub()
    print(\'world\')

def sub():
    greenlet.getcurrent().parent.switch()

g = greenlet(parent)
g.switch()
print(\'here is switched from the sub generator\')
g.switch()

这段代码的输出是

hello
here is switched from the sub generator
world

改用greenlet之后,协程之间的跳转就变得非常随意了。比如sub里可以直接把执行权交给main,而parent完全不知情。从视觉上来看parent的实现里完全不能知道在sub内部发生了switch。
虽然不能和多线程相比,但是效果是类似的。对于多线程的代码,是任何一行代码都可能与其他线程并行。类似greenlet的隐式的协程,虽然不是每一行代码都可能产生switch。虽然产生switch的地方其实和用yield写是一样多,而且也是一样固定的。但是因为缺少强制的yield,使得在不阅读被调用函数内部的实现的前提下,无法提前知道这个调用是否会产生执行权的迁移。加上协程之间有共享状态的话,一定程度上会产生类似多线程的并发读写状态的bug。

相关内容

热门资讯

Mobi、epub格式电子书如... 在wps里全局设置里有一个文件关联,打开,勾选电子书文件选项就可以了。
定时清理删除C:\Progra... C:\Program Files (x86)下面很多scoped_dir开头的文件夹 写个批处理 定...
scoped_dir32_70... 一台虚拟机C盘总是莫名奇妙的空间用完,导致很多软件没法再运行。经过仔细检查发现是C:\Program...
500 行 Python 代码... 语法分析器描述了一个句子的语法结构,用来帮助其他的应用进行推理。自然语言引入了很多意外的歧义,以我们...
小程序支付时提示:appid和... [Q]小程序支付时提示:appid和mch_id不匹配 [A]小程序和微信支付没有进行关联,访问“小...
pycparser 是一个用... `pycparser` 是一个用 Python 编写的 C 语言解析器。它可以用来解析 C 代码并构...
微信小程序使用slider实现... 众所周知哈,微信小程序里面的音频播放是没有进度条的,但最近有个项目呢,客户要求音频要有进度条控制,所...
65536是2的几次方 计算2... 65536是2的16次方:65536=2⁶ 65536是256的2次方:65536=256 6553...
Apache Doris 2.... 亲爱的社区小伙伴们,我们很高兴地向大家宣布,Apache Doris 2.0.0 版本已于...
项目管理和工程管理的区别 项目管理 项目管理,顾名思义就是专注于开发和完成项目的管理,以实现目标并满足成功标准和项目要求。 工...