gpt4 book ai didi

python - Asyncio 与 Gevent

转载 作者:太空狗 更新时间:2023-10-29 19:26:28 25 4
gpt4 key购买 nike

关闭。这个问题是opinion-based .它目前不接受答案。












想改善这个问题吗?更新问题,以便可以通过 editing this post 用事实和引文回答问题.

2年前关闭。




Improve this question




背景

我曾经在一个 Python2 系统上工作过,该系统有很多同步编写的自定义 I/O 代码,并使用线程进行扩展。在某些时候,我们无法进一步扩展它,并意识到我们必须切换到异步编程。

  • Twisted是流行的选择,但我们想避免它的回调 hell 。
  • 它确实有 @inlineCallbacks 装饰器,它使用生成器魔法有效地实现了协程,其他一些库也是如此。这更能忍受,但感觉有点片状。
  • 然后我们找到了gevent .您所要做的就是:
  • from gevent import monkey
    monkey.patch_all()

    就像那样,你所有的标准 I/O - 套接字、数据库事务、用纯 Python 编写的一切,真的 - 都是异步的,使用 greenlets 在幕后产生和切换。

    它并不完美:
  • 当时,它在 Windows 上运行不佳(今天仍然有一些限制)。幸运的是,我们在 Linux 上运行。
  • 例如,它无法修补 C 扩展,因此我们无法使用 MySQLdb。幸运的是,有许多纯 Python 替代品,例如 PyMySQL。



  • 如今,Python 3 更受欢迎,随之而来的是 - asyncio .就我个人而言,我认为这很棒,但最近有人问我它与我们用 gevent 实现的有什么不同,但我想不出一个足够好的答案。

    这听起来可能很主观,但我实际上是在寻找 实际用例其中一个会显着优于另一个,或者允许其他人不做的事情。以下是我迄今为止收集的注意事项:
  • 就像我说的,gevent 在 Windows 上相当有限。再说一次,我知道的大多数生产代码都在 Linux 上运行。

    如果需要在 Windows 上运行,请使用 asyncio .
  • Gevent 不能对 C 扩展进行猴子补丁。但是,asyncio 不能修补任何东西。

    想象一下,出现了一种新的 DB 技术,您想使用它,但是没有一个纯粹的 Python 库,因此您无法将其与 Gevent 集成。问题是,当没有可以与 asyncio 集成的 io* 库时,您就会陷入困境!当然有工作线程和执行程序,但这不是重点,无论如何在两种情况下都可以正常工作。
  • 有人说这是个人品味的问题,但我认为可以公平地说同步编程本质上比异步编程更容易(想一想:你有没有遇到过一个可以使用套接字的新手程序员,但很难理解如何正确地选择/投票他们,或者在 future / promise 中思考?你有没有遇到过相反的情况?)。

    无论如何,我们不要去那里。我想解决这个问题,因为它经常出现(here's 一个关于 reddit 的讨论),但我真正想要的是你有实际理由使用其中一个的场景。
  • Asyncio 是标准库的一部分。这很重要:这意味着它维护良好,文档齐全,并且每个人都知道它并默认使用它。

    但是,考虑到使用 Gevent 需要知道的很少(并且它的维护和文档也非常好),它似乎并不重要。因此,虽然对于涉及 future 的最复杂场景,StackOverflow 上有多个答案,但根本不使用 future 的可能性似乎同样可行。

  • 肯定 Guido 和 Python 社区有充分的理由在 Asyncio 上投入这么多精力,甚至在语言中引入新的关键字——我似乎找不到它们。

    两者之间的主要区别是什么,在什么情况下会变得明显?

    最佳答案

    来自实际使用的“简单”答案:

  • gevent 的好处——你可以打补丁,这意味着你[理论上]可以使用同步库。 IE。你可以修补django。
  • gevent 的坏处——不是所有的东西都可以打补丁,如果你必须使用一些不能打补丁的数据库驱动程序,你就完蛋了
  • 关于 gevent 最糟糕的事情 - 它是“神奇的”。了解“patch_all”会发生什么所需的工作量是巨大的,同样的工作也适用于为您的开发团队寻找/雇用新人。更糟糕的是——调试基于 gevent 的代码是 hell 。我会说,如果不是更糟的话,与回调几乎一样。

  • 我认为后面的点是关键。软件工程中最被低估的事情是代码是用来阅读的,而不是用来编写或有效运行的(如果以后是这种情况,你宁愿从 python 切换到系统级语言)。 Asyncio 带来了异步编程的缺失部分——预定义和受控的上下文切换点。您实际上在编写同步代码(即您没有考虑突然的线程切换、锁、队列等),并使用 await ...当您知道 call 是 IO 阻塞时,因此您让事件循环选择其他内容,即为 CPU 做好准备,然后再获取当前状态。

    这就是 asyncio 如此出色的原因——它易于维护。缺点是几乎所有的“世界”也必须是异步的——DB 驱动程序、http 工具、文件处理程序。有时你会丢失库,这几乎可以保证。

    关于python - Asyncio 与 Gevent,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54254252/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com