Python异步io流 [英] Python async io stream

查看:100
本文介绍了Python异步io流的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在查看异步文档中的以下代码.

I was going through following code in the asyncio doc.

import asyncio

async def tcp_echo_client(message):
  reader, writer = await asyncio.open_connection(
    '127.0.0.1', 8888)

  print(f'Send: {message!r}')
  writer.write(message.encode())

  data = await reader.read(100)
  print(f'Received: {data.decode()!r}')

  print('Close the connection')
  writer.close()
  await writer.wait_closed()

asyncio.run(tcp_echo_client('Hello World!'))

但是,我现在能够理解为什么可以等待reader.read而不是writer.write了?由于它们都是I/O操作,因此写方法还应该等待吗?

However I am now able to understand why reader.read is awaitable but writer.write is not ? Since they are both I/O operations write method should also be awaitable right ?

推荐答案

但是,我现在能够理解为什么可以等待reader.read而不是writer.write了?因为它们都是I/O操作,所以写方法也应该是可以等待的吧?

However I am now able to understand why reader.read is awaitable but writer.write is not ? Since they are both I/O operations write method should also be awaitable right ?

不一定. read() write() read()必须返回实际数据,而write()纯粹是出于副作用.所以read() 必须是可以等待的,因为当数据尚不可用时,它需要挂起调用协程.另一方面,write()可以(通过在异步中实现)通过将数据存储在某个缓冲区中并安排将其写入适当的时间来实现.

Not necessarily. The fundamental asymmetry between read() and write() is that read() must return actual data, while write() operates purely by side effect. So read() must be awaitable because it needs to suspend the calling coroutine when the data isn't yet available. On the other hand, write() can be (and in asyncio is) implemented by stashing the data in some buffer and scheduling it to be written at an opportune time.

此设计具有重要的后果,例如,写入数据的速度快于另一面的读取速度,这会导致缓冲区无限膨胀,并且有效地丢失了write()期间的异常.可以通过调用 writer.drain() 会应用 backpressure ,即将缓冲区写出到OS,必要时将协程挂起.直到缓冲区大小降至阈值. write()文档建议对write()的调用应后跟drain()."

This design has important consequences, such as that writing data faster than the other side reads it causes the buffer to bloat up without bounds, and that exceptions during write() are effectively lost. Both issues are fixed by calling writer.drain() which applies backpressure, i.e. writes out the buffer to the OS, if necessary suspending the coroutine in the process. This is done until the buffer size drops beneath a threshold. The write() documentation advises that "calls to write() should be followed by drain()."

write()中缺少反压是由于在基于回调的层之上实现了异步流的结果,在该层中,非异步write()比完全异步的替代方案更方便使用.参见此文章Nathaniel J Smith /python-trio/trio"rel =" nofollow noreferrer>三重奏,以详细了解该主题.

The lack of backpressure in write() is a result of asyncio streams being implemented on top of a callback-based layer in which a non-async write() is much more convenient to use than a fully asynchronous alternative. See this article by Nathaniel J Smith, the author of trio, for a detailed treatment of the topic.

这篇关于Python异步io流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆