【发布时间】:2019-05-29 19:25:29
【问题描述】:
我正在使用一个网络库,它提供了一个包装器,用于将其协程函数与asyncio 一起使用。当我写了一个随机关闭连接的测试(看看我的程序在恶劣条件下是否有弹性)时,我发现它无限期挂起。
这似乎是我正在使用的库提供的包装器中的一个错误,因为程序挂起等待来自loop.add_reader() 或loop.add_writer() 的回调,但后来我找不到如何在套接字时收到通知已关闭。
这是一个显示我的程序发生了什么的最小程序:
import asyncio
import socket
async def kill_later(c):
await asyncio.sleep(0.1)
c.close()
async def main():
loop = asyncio.get_running_loop()
c = socket.create_connection(('www.google.com', 80))
c.setblocking(0)
ev = asyncio.Event()
loop.add_reader(c, ev.set)
# Closes the socket after 0.1 ms:
asyncio.create_task(kill_later(c))
print("waiting...")
#### ↓ THIS WAITS FOREVER ↓ ####
await ev.wait()
asyncio.run(main())
我的问题:如何通知套接字被asyncio 循环关闭?
编辑:由于大众的需求,使套接字成为非阻塞的,但这并没有什么区别,因为add_reader() 不会尝试在套接字上执行任何 IO,只是观察它何时准备好。
【问题讨论】:
-
阻塞与否没有区别,
loop.add_reader()将套接字添加到epoll,它不会尝试从中读取。
标签: python python-asyncio python-3.7