使用 asyncio 的非阻塞 I/O [英] Non-blocking I/O with asyncio
问题描述
我正在尝试使用 Pygame 和 asyncio 编写网络游戏,但我不知道如何避免读取挂起.这是我的客户端代码:
I'm trying to write a networked game with Pygame and asyncio, but I can't work out how to avoid hanging on reads. Here is my code for the client:
@asyncio.coroutine
def handle_client():
print("Connected!")
reader, writer = yield from asyncio.open_connection('localhost', 8000)
while True:
mouse_up = False
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.MOUSEBUTTONUP:
mouse_up = True
if mouse_up:
print("Writing")
writer.write(b"Mouse up")
print("Waiting to read")
line = yield from reader.read(2**12)
print(line.decode())
writer.close()
这挂在 line = yield from reader.read(2**12)
行上.我以前认为 asyncio 的要点是它是非阻塞的,所以如果没有任何数据要读取,它就会继续执行.我现在明白事实并非如此.
This hangs on the line line = yield from reader.read(2**12)
. I previously thought that the point of asyncio was that it was non-blocking, and so if there wasn't any data to read it would just continue executing. I see now that this isn't the case.
如何将 asyncio 网络代码与 Pygame 绘图和事件代码集成?
How do I integrate the asyncio networking code with the Pygame drawing and event code?
推荐答案
yield from
的要点是将执行切换到 asyncio 的事件循环 和 以阻止当前协程,直到结果可用.要在不阻塞当前协程的情况下安排任务,您可以使用 asyncio.async()
.
The point of yield from
is to switch the execution to the asyncio's event loop and to block the current coroutine until the result is available. To schedule a task without blocking the current coroutine, you could use asyncio.async()
.
在不阻塞 pygame 循环的情况下打印读取到的数据:
To print read-so-far data without blocking the pygame loop:
@asyncio.coroutine
def read(reader, callback):
while True:
data = yield from reader.read(2**12)
if not data: # EOF
break
callback(data)
@asyncio.coroutine
def echo_client():
reader, ...
chunks = []
asyncio.async(read(reader, chunks.append))
while True:
pygame.event.pump() # advance pygame event loop
...
if chunks: # print read-so-far data
print(b''.join(chunks).decode())
del chunks[:]
yield from asyncio.sleep(0.016) # advance asyncio loop
while
循环内不应有阻塞调用.
There should be no blocking calls inside the while
loop.
read()
和 sleep()
协程在同一个线程中并发运行(显然你也可以同时运行其他协程).
read()
and sleep()
coroutines run concurrently in the same thread (obviously you could run other coroutines concurrently too).
这篇关于使用 asyncio 的非阻塞 I/O的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!