作家
登录

理解Python asyncio内部实现机制

作者: 来源: 2017-09-05 08:58:59 阅读 我要评论

这里我不禁想问,为什么大年夜家没有一开端就想到 async/await 的方法呢?我的一个假设是 async/await 是须要说话本身的支撑的,而写编译器/说冥器的专家不必定有编写竽暌功用的丰富经验,是很可能大年夜一开端就拒绝如许的修改的。是以法度榜样员们只能本身用库的情势添加支撑了。当然这纯粹是猜测,只想感慨下不合范畴的隔阂。

总而言之,有了 event loop 我们就能经由过程回调函数来完成异步编程,但这种方法异常不友爱,是以人们又提出了类似 Promise 的思惟,让我们能次序编写异步代码,最后经由过程说话对 async/await 的语法支撑,异步与同步代码的构培养几乎达到同一。这种同一有很重要的意义,它使我们能以同步的思维去懂得异步的代码而不受回调方法的代码构造的影响。

而这一切都是为了将不合的异步函数“链接”起来,只不过是 async/await 的方法最为便利。比较线程,操作体系是没有供给方法将不合的线程链接起来的,是以这种将不合的协程链接起来的对象是协程比线程好的一个方面。

高低文切换(恢复控制流)

这里举一个 Python 官方文档 的例子:

  1. import asyncio  
  2. async def compute(x, y): 
  3.  print("Compute %s + %s ..." % (x, y)) 
  4.  await asyncio.sleep(1.0) 
  5.  return x + y  
  6. async def print_sum(x, y): 
  7.  result = await compute(x, y) 
  8.  print("%s + %s = %s" % (x, y, result))  
  9. loop = asyncio.get_event_loop() 
  10. loop.run_until_complete(print_sum(1, 2)) 
  11. loop.close() 

膳绫擎的代码的履行流程是:

懂得Python asyncio内部实现机制

这里有两个问题:

  1. 谁向 event loop 注册了事宜(及回调)?
  2. 法度榜样大年夜哪里恢复履行?

法度榜样大年夜 print_sum 开始履行,履行到 asyncio.sleep 时须要暂停,那么肯定是在 sleep 中向 event loop 注册了急鹞鲼事宜。那们问题来了,当法度榜样恢复履行时,它应当大年夜哪里恢复呢?

大年夜膳绫擎的流程图中,可以看见它是大年夜 print_sum 开端恢复,但如许的话, sleep 注册事宜时就须要知道是谁(即 print_sum )调用了它,如许才能在 callback 中指定大年夜 print_sum 开端恢复履行!

但如不雅不是大年夜 print_sum 恢复履行,那么一样的,大年夜 sleep 恢复履行后, sleep 须要知道接下来返回到什愦地位(即 compute 函数中的 await 地位), asyncio 又是若何做到这点的?

那么事实(代码实现)是如何的呢?

当我们把一个协程用 loop.run_until_complete (或其它类似办法)履行时, event loop 会把它担保成一个 Task 。当协程开端履行或被唤醒时,Task 的 _step 办法会被调用, 这里 它会调用 coro.send(None) 来履行/唤醒它担保着的协程。

  1. if exc is None: 
  2.  # We use the `send` method directly, because coroutines 
  3.  # don't have `__iter__` and `__next__` methods. 
  4.  result = coro.send(None) 
  5. else
  6.  result = coro.throw(exc) 

留意到这老将 coro.send 的结不雅赋值给了 result ,那么它会返回什么呢?在我们这个例子中,协程链的最末尾是 asyncio.sleep ,我们看看 它的实现 :

  1. @coroutine 
  2. def sleep(delay, result=None, *, loop=None): 
  3.  """Coroutine that completes after a given time (in seconds).""" 
  4.  if delay == 0: 
  5.  yield 
  6.  return result 
  7.  
  8.  if loop is None: 

      推荐阅读

      Android必知必会-使用Intent打开第三方应用及验证可用性

    基本常识此方法多用于启动体系中的功能性应用,比如打德律风、发邮件、预览图片、应用默认浏览器打开一个网页等。1. App 的人口 Activity 与其 icon一个通俗的应用默认会有一小我口 Activ>>>详细阅读


    本文标题:理解Python asyncio内部实现机制

    地址:http://www.17bianji.com/lsqh/37131.html

关键词: 探索发现

乐购科技部分新闻及文章转载自互联网,供读者交流和学习,若有涉及作者版权等问题请及时与我们联系,以便更正、删除或按规定办理。感谢所有提供资讯的网站,欢迎各类媒体与乐购科技进行文章共享合作。

网友点评
自媒体专栏

评论

热度

精彩导读
栏目ID=71的表不存在(操作类型=0)