Python 3.7+Асинхронное программированиепонятие
asyncio.BufferedProtocol
протоколы и транспорты
Потоковый протокол с ручным буфером: цикл просит буфер через get_buffer(), пишет в него данные и сообщает их длину в buffer_updated(). Появился в Python 3.7.
Синтаксис
class P(asyncio.BufferedProtocol): def get_buffer(self, sizehint): ...; def buffer_updated(self, nbytes): ...
Учащемуся этот уровень обычно не нужен: для TCP есть потоки asyncio.open_connection() и asyncio.start_server(), для процессов — asyncio.create_subprocess_exec(). BufferedProtocol — оптимизация поверх Protocol: данные пишутся прямо в ваш bytearray без создания нового bytes на каждую порцию. Это выигрыш только при очень больших потоках; get_buffer() обязан вернуть непустой изменяемый буфер, а читать надо ровно nbytes из buffer_updated(), а не весь буфер — хвост там остался от прошлых порций.
Примеры
import asyncio
import socket
class Reader(asyncio.BufferedProtocol):
def __init__(self):
self.buf = bytearray(16)
self.chunks = []
def get_buffer(self, sizehint):
return self.buf
def buffer_updated(self, nbytes):
self.chunks.append(bytes(self.buf[:nbytes])) # ровно nbytes, не весь буфер
async def main():
loop = asyncio.get_running_loop()
left, right = socket.socketpair()
transport, proto = await loop.create_connection(Reader, sock=left)
right.sendall(b'hello')
await asyncio.sleep(0.01)
print(proto.chunks) # → [b'hello']
transport.close()
right.close()
asyncio.run(main())
См. также
Открыть в полном глоссарииdocs.python.orgСообщить о неточности