相关疑难解决方法(0)

asyncio实际上如何工作?

这个问题是由我的另一个问题推动的:如何在cdef中等待?

网上有大量的文章和博客文章asyncio,但它们都非常肤浅.我找不到任何有关如何asyncio实际实现的信息,以及I/O异步的原因.我试图阅读源代码,但它是成千上万行不是最高级别的C代码,其中很多处理辅助对象,但最重要的是,很难在Python语法和它将翻译的C代码之间建立连接成.

Asycnio自己的文档甚至没那么有用.没有关于它是如何工作的信息,只有关于如何使用它的一些指导,这些指导有时也会误导/写得很差.

我熟悉Go的coroutines实现,并且希望Python做同样的事情.如果是这种情况,我在上面链接的帖子中出现的代码就可以了.既然没有,我现在正试图找出原因.到目前为止我最好的猜测如下,请纠正我错在哪里:

  1. 表单的过程定义async def foo(): ...实际上被解释为类继承的方法coroutine.
  2. 也许,async def实际上是通过await语句拆分成多个方法,其中调用这些方法的对象能够跟踪到目前为止通过执行所做的进度.
  3. 如果上述情况属实,那么,从本质上讲,协程的执行归结为一些全局管理器调用协程对象的方法(循环?).
  4. 全局管理器以某种方式(如何?)了解I/O操作何时由Python(仅?)代码执行,并且能够在当前执行方法放弃控制之后选择一个待执行的协程方法执行(命中await语句) ).

换句话说,这是我尝试将某些asyncio语法"贬低"为更容易理解的东西:

async def coro(name):
    print('before', name)
    await asyncio.sleep()
    print('after', name)

asyncio.gather(coro('first'), coro('second'))

# translated from async def coro(name)
class Coro(coroutine):
    def before(self, name):
        print('before', name)

    def after(self, name):
        print('after', name)

    def __init__(self, name):
        self.name = name
        self.parts = self.before, self.after
        self.pos = 0

    def __call__():
        self.parts[self.pos](self.name)
        self.pos += 1

    def …
Run Code Online (Sandbox Code Playgroud)

python python-3.x python-asyncio

64
推荐指数
5
解决办法
1万
查看次数

asyncio:为什么默认情况下它不是非阻塞的

默认情况下,asyncio同步运行协同程序.如果它们包含阻塞IO代码,它们仍会等待它返回.解决这个问题的方法是loop.run_in_executor()将代码转换为线程.如果线程在IO上阻塞,则另一个线程可以开始执行.所以你不要浪费时间等待IO调用.

如果您在asyncio没有执行者的情况下使用,那么您将失去这些加速.所以我想知道,为什么你必须明确地使用执行器.为什么不默认启用它们?(在下文中,我将重点关注http请求.但它们实际上只是作为一个例子.我对一般原则感兴趣.)

经过一番搜索,我找到了aiohttp.它是一个基本上提供asyncio和组合的库requests:非阻塞HTTP调用.使用执行程序,asyncio并且requests表现得非常像aiohttp.是否有理由实施新库,您是否因使用执行程序而支付性能损失?

回答了这个问题:为什么asyncio总是不使用执行程序? Mikhail Gerasimov向我解释过,执行程序会启动操作系统线程并且它们会变得昂贵.因此,不将它们作为默认行为是有道理的.aiohttprequests在执行程序中使用模块更好,因为它提供只有协同程序的非阻塞代码.

这让我想到了这个问题.aiohttp将自己宣传为:

用于asyncio和Python的异步HTTP客户端/服务器.

所以aiohttp是基于asyncio?为什么不asyncio提供只有协同程序的非阻塞代码呢?这将是理想的默认值.

或者aiohttp实现了这个新的事件循环(没有OS线程)本身?在那种情况下,我不明白他们为什么要宣传自己为基础asyncio.Async/await是一种语言功能.Asyncio是一个事件循环.如果aiohttp有自己的事件循环,那么应该有很少的交集asyncio.实际上,我认为这样的事件循环将比http请求更大.

python multithreading asynchronous python-asyncio aiohttp

1
推荐指数
1
解决办法
505
查看次数