为什么只有异步函数才能产生异步代码?

Aleksey Bilogur

在文章“我没有感觉到异步压力”中, Armin Ronacher进行了以下观察:

在线程代码中,任何函数都可以产生。在异步代码中,只有异步函数可以。例如,这意味着writer.write方法无法阻止。

此观察是参考以下代码示例进行的:

from asyncio import start_server, run

async def on_client_connected(reader, writer):
    while True:
        data = await reader.readline()
        if not data:
            break
        writer.write(data)

async def server():
    srv = await start_server(on_client_connected, '127.0.0.1', 8888)
    async with srv:
        await srv.serve_forever()

run(server())

我不明白这个评论。特别:

  • yield在异步函数内部,为什么同步函数不能
  • 什么是yield有阻塞的执行呢?为什么不能yield,不能阻止功能?
Aleksey Bilogur

逐行进行:

在线程代码中,任何函数都可以产生。

在机器上运行的程序是按照流程进行组织的每个进程可以具有一个或多个线程线程(如进程)由操作系统调度(并可由操作系统中断)。在此上下文中,单词“ yield”表示“让其他代码运行”。当工作被拆分到多个线程之间时,函数很容易“屈服”:操作系统将一个线程中运行的代码挂起,在另一个线程中运行一些代码,将其挂起,然后返回,然后在第一个线程上进行更多工作,等等。上。通过以这种方式在线程之间切换,可以实现并发。

在此执行模型中,暂停的代码是同步的还是异步的都没有关系。代码的线程正在运行的行由行,所以同步功能的基本假设---发生在运行一个代码行和下一之间---不受侵犯没有变化。

在异步代码中,只有异步函数可以。

在本文中,“异步代码”是指单线程应用程序,其功能与多线程应用程序相同,不同之处在于它通过线程中使用异步函数来实现并发,而不是不同线程之间进行拆分在此执行模型中,解释器(而不是操作系统)负责根据需要在功能之间进行切换以实现并发性。

在此执行模型中,将工作挂在位于异步函数内部的同步函数中间是不安全的。这样做意味着在运行同步功能的过程中运行其他一些代码,从而破坏了同步功能所做的“逐行”假设。

结果,解释器将仅等待同步子功能之间的异步功能的执行暂停,而不会等待一个子功能。这就是异步代码中的同步函数无法产生的语句的含义:一旦同步函数开始运行,它就必须完成。

例如,这意味着writer.write方法无法阻止。

writer.write方法是同步的,因此,在异步程序中运行时,方法是不间断的。如果要阻塞此方法,则它将不仅阻塞正在其内部运行的异步函数,还将阻塞整个程序。那将是不好的。writer.write避免通过写入写缓冲区并立即返回来阻塞程序。

严格来说,writer.write 可以阻止,这样做是不明智的。

如果您需要在异步函数中进行阻止,则正确的方法是使用await另一个异步函数。这就是例如await writer.drain()这将异步阻止:尽管此特定功能仍处于阻止状态,但它将正确地屈服于其他可以运行的功能。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

为什么我的异步代码没有运行异步?

来自分类Dev

具有异步请求的递归函数

来自分类Dev

具有异步委托的异步函数的命名约定

来自分类Dev

伪造的异步函数。为什么?

来自分类Dev

带有异步的异步模式=全部

来自分类Dev

具有异步关闭变量的结构函数

来自分类Dev

制作具有异步构造函数的对象数组

来自分类Dev

具有异步函数的 Python 多处理

来自分类Dev

为什么这种异步代码有时会失败,而且只有在没有观察到的时候才失败?

来自分类Dev

为什么这种异步代码有时会失败,并且只有在没有观察到的情况下才会失败?

来自分类Dev

如何进行循环等待所有异步功能完成。异步函数里面有多个异步函数

来自分类Dev

为什么在仅使用python 3.5的Jupyter笔记本中,给出SyntaxError:具有异步def的无效语法?

来自分类Dev

为什么只有带有内联类型的函数才能检测到额外的字段?

来自分类Dev

异步编程,为什么不执行代码

来自分类Dev

为什么这个异步代码不停止?

来自分类Dev

为什么这个 Javascript 代码是异步的?

来自分类Dev

为什么只有某些javascript函数才能在HTML脚本标签中使用?

来自分类Dev

为什么void方法要异步才能等待?

来自分类Dev

为什么将列表理解与带有异步的协程一起使用时,为什么会得到不同的结果?

来自分类Dev

带有异步的多个循环

来自分类Dev

带有异步的互递协程

来自分类Dev

具有异步功能的JavaScript数组

来自分类Dev

带有异步Dapper方法的CancellationToken?

来自分类Dev

具有异步请求的NodeJS

来自分类Dev

取消所有异步任务

来自分类Dev

具有异步结构的openxml

来自分类Dev

具有异步功能的OracleCommand ExecuteNonQuery

来自分类Dev

Laravel + Vuejs有异步问题的麻烦

来自分类Dev

具有异步功能的装饰器

Related 相关文章

  1. 1

    为什么我的异步代码没有运行异步?

  2. 2

    具有异步请求的递归函数

  3. 3

    具有异步委托的异步函数的命名约定

  4. 4

    伪造的异步函数。为什么?

  5. 5

    带有异步的异步模式=全部

  6. 6

    具有异步关闭变量的结构函数

  7. 7

    制作具有异步构造函数的对象数组

  8. 8

    具有异步函数的 Python 多处理

  9. 9

    为什么这种异步代码有时会失败,而且只有在没有观察到的时候才失败?

  10. 10

    为什么这种异步代码有时会失败,并且只有在没有观察到的情况下才会失败?

  11. 11

    如何进行循环等待所有异步功能完成。异步函数里面有多个异步函数

  12. 12

    为什么在仅使用python 3.5的Jupyter笔记本中,给出SyntaxError:具有异步def的无效语法?

  13. 13

    为什么只有带有内联类型的函数才能检测到额外的字段?

  14. 14

    异步编程,为什么不执行代码

  15. 15

    为什么这个异步代码不停止?

  16. 16

    为什么这个 Javascript 代码是异步的?

  17. 17

    为什么只有某些javascript函数才能在HTML脚本标签中使用?

  18. 18

    为什么void方法要异步才能等待?

  19. 19

    为什么将列表理解与带有异步的协程一起使用时,为什么会得到不同的结果?

  20. 20

    带有异步的多个循环

  21. 21

    带有异步的互递协程

  22. 22

    具有异步功能的JavaScript数组

  23. 23

    带有异步Dapper方法的CancellationToken?

  24. 24

    具有异步请求的NodeJS

  25. 25

    取消所有异步任务

  26. 26

    具有异步结构的openxml

  27. 27

    具有异步功能的OracleCommand ExecuteNonQuery

  28. 28

    Laravel + Vuejs有异步问题的麻烦

  29. 29

    具有异步功能的装饰器

热门标签

归档