Dan*_*tik 18 python gevent python-asyncio
我曾经在一个Python2系统上工作,该系统具有许多同步编写的自定义I / O代码,并使用线程进行了扩展。在某个时候,我们无法进一步扩展它,并意识到我们必须切换到异步编程。
@inlineCallbacks装饰器,该装饰器与其他一些库一样,使用生成器魔术有效地实现了协程。那是可以忍受的,但感觉有点片状。from gevent import monkey
monkey.patch_all()
就像那样,您的所有标准I / O(套接字,数据库事务以及用纯Python编写的所有内容)实际上都是异步的,使用greenlet产生并在后台切换。
这不是完美的:
如今,Python 3更加流行,并且有了它-asyncio。就个人而言,我认为这很棒,但是最近有人问我,它比我们使用gevent做的更好吗?无法给出足够好的答案。
这听起来可能是主观的,但是我实际上是在寻找一个实际的用例,其中一个将大大优于另一个,或者允许另一个不这样做。到目前为止,这是我收集的注意事项:
就像我说的那样,gevent在Windows上非常受限制。再说一次,我所知道的大多数生产代码都在Linux上运行。
如果需要在Windows上运行,请使用asyncio。
Gevent无法猴子C扩展。但是,asyncio无法猴子修补任何东西。
想象一下,出现了一种新的数据库技术,并且您想使用它,但是它没有一个纯Python库,因此您无法将其与Gevent集成。问题是,当没有可以与asyncio集成的io *库时,您就像被困一样!当然,有工作线程和执行程序,但这不是重点,无论如何在两种情况下都一样好。
有人说这是个人喜好,但我认为可以说同步编程从本质上讲要比异步编程更容易(请考虑一下:您是否遇到过可以使用套接字的新手程序员,但是很难理解如何正确选择/投票,或考虑期货/承诺?您遇到过相反的情况吗?)。
无论如何,我们不要去那里。我想解决这一点,因为它经常出现(这是关于reddit的讨论),但是我真正要关注的是您有实际理由使用其中一种的情况。
Asyncio是标准库的一部分。这是巨大的:这意味着它得到了很好的维护,良好的记录,并且每个人都知道它并默认使用它。
但是,考虑到您需要使用Gevent的知识很少(并且它也得到很好的维护和记录),它似乎并不重要。因此,即使对于涉及期货的最复杂的方案,StackOverflow上也有多个答案,但根本不使用期货的可能性似乎也是可行的。
那么:asyncio盛行的一些具体用例是什么?当然,Guido和Python社区有充分的理由对此投入大量精力,甚至在语言中引入了新的关键字-我似乎找不到它们。
实际使用情况中的“简单”答案:
我认为稍后一点很关键。软件工程中最被低估的是代码只能被读取,编写或有效运行(如果以后是这种情况,您宁愿从python切换到系统级语言)。Asyncio缺少用于异步编程的部分- 预定义和受控的上下文切换点。您实际上是在编写同步代码(即,您不是在考虑突然的线程切换,锁,队列等),await ...而是在知道调用受到IO阻塞的情况下使用,因此您可以让事件循环选择适合CPU的其他功能,稍后再获取当前状态。
这就是使asyncio如此出色的原因-易于维护。不利之处在于,几乎所有“世界”也必须是异步的-数据库驱动程序,http工具,文件处理程序。有时您会缺少库,这是可以保证的。