什么是格林莱特?

问题描述 投票:0回答:2

我是gevent的新手。我已经阅读了gevent

的介绍

他们提供了简单的示例,但我很难理解 greenlet 是什么。来自学习并发。

Greenlets are a very lightweight coroutine written in C that
are cooperatively scheduled. They provide us with a very lightweight thread-
like object that allows us to achieve concurrent execution within our Python
programs without incurring the cost of spinning up multiple threads.

Greenlet 不是线程? 同步点是如何定义的?有人可以举例说明吗?

python gevent
2个回答
14
投票

同步编程一次只能做一件事。因此,当数据库查询正在运行时,其他人(例如通过 Web 框架拉取网页)必须等待其完成。

Gevent 通过使用上下文切换和事件使其异步。这是什么意思?这样想吧。你有一个队列,里面有等待事情发生的东西,同时 gevent 说,好吧,你可以等待,我将转到下一个任务,并在等待你完成的同时开始做事情(比如数据库读取,或者等待用于用户输入),当您完成后,当我返回队列并且您说您已准备好进行下一步时,我会为您专注于此。

通过这种方式,虽然仍然是单线程,但应用程序可以在作业之间超快速地切换,不断检查状态以查看它是否值得关注,同时,其他事情可以在等待您时完成。

与由操作系统处理且繁重的多线程相反,它们需要自己的资源并且在之间切换的成本很高。

Gevent 可以轻松地将通常使用线程的内容转换为 greenlet。


2
投票

greenlet 是 CPython C 堆栈上的连续帧块,可以交换到堆中。

这是实现协程所需的一般基本构建块。

Python 中的原生协程实现不会将 C 帧保存到堆中。它被设计为 C 堆栈上没有重要数据,然后在挂起/恢复协程时使用

send()
yield [from]
展开/重建 C 堆栈的每个帧。这样做的缺点是,您需要在整个代码库中不必要地发送
yield from
的垃圾邮件链,并承受堆栈展开/重建的所有开销。总体而言,原生 Python 生成器在性能和语法支持方面相当薄弱。

Stackless python 避免使用 C 堆栈 来进行 Python 函数调用(因为如果没有有用的上下文,那还有什么意义呢?)。所有需要的上下文都存储在Python框架中(其中有Python堆栈、IP、本地变量、返回框架等)。 PyPy 包含 Stackless Python,这是它的性能如此出色的部分原因。

Greenlets 的灵感来自 Stackless python。作为 CPython 的扩展模块,C 堆栈仍然用于 Python 函数调用,但您可以按需将帧块(该块“是”协程/greenlet)交换到堆。现在,您可以根据需要混合执行协程来实现目标。这样你就可以得到比 CPython 中的生成器更好的东西,而不必完全切换到 PyPy。

© www.soinside.com 2019 - 2024. All rights reserved.