这个问题是由我的另一个问题如何在cdef等待?引起的
网上有大量关于asyncio
的文章和博客文章,但它们都非常肤浅。我找不到任何关于asyncio
如何实际实现的信息,以及什么使I/O异步。我试图阅读源代码,但它有数千行不是最高级的C代码,其中很多处理辅助对象,但最重要的是,它很难将Python语法和它将转换成的C代码联系起来。
Asycnio自己的文档就更没有帮助了。这里没有关于它如何工作的信息,只有一些关于如何使用它的指南,这些指南有时也会误导/写得很糟糕。
我熟悉Go的协程实现,并希望Python也能做同样的事情。如果是这样的话,我在上面链接的帖子中出现的代码应该是有效的。既然它没有,我现在正试图找出原因。到目前为止,我最好的猜测如下,请纠正我的错误:
async def foo(): ...
的过程定义实际上被解释为继承coroutine
的类的方法。async def
实际上被await
语句分割成多个方法,其中调用这些方法的对象能够跟踪到目前为止执行的进度。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 done(self):
return self.pos == len(self.parts)
# translated from asyncio.gather()
class AsyncIOManager:
def gather(*coros):
while not every(c.done() for c in coros):
coro = random.choice(coros)
coro()
如果我猜对了,那我就有麻烦了。在这种情况下,I/O实际上是如何发生的?在一个单独的线程?整个解释器挂起,I/O发生在解释器之外吗?I/O到底是什么意思?如果我的python过程称为c__abc0过程,它反过来发送中断到内核,放弃控制它,python解释器如何知道这一点,并能够继续运行一些其他代码,而内核代码进行实际的I/O,直到它唤醒最初发送中断的python过程?原则上,Python解释器如何意识到这种情况?