在 asyncio 的 streams 中设置超时
asyncio 的流是高层级原语。使用流可以简化 TCP socket 编程,并可以提高并发连接的性能。
但开始使用时,我们发现,它的读写操作方法中,均没有超时的参数。例如,如果对方不发送信息,StreamRead 的 read 就会一直等下去。StreamRead 和 StreamWriter 类中,也没有 xxx_nowait 之类的非阻塞操作方法。StreamWriter 的 write 方法是个不等待的同步方法,但一般要使用 drain 来等待写的结束,这也是一个异步阻塞的方法。
其实用惯了asyncio后就会发现,asyncio 的超时处理是用 wait_for方法实现的,例如,你可以将:
data = await reader.read(100)
改为:
data = await asyncio.wait_for(reader.read(100), timeout=4)
就可以实现超时退出了,上面的例子是等待4秒收不到数据就退出。
应当注意的是:超时以后,并不是直接中断语句的执行,转向下一句,而是抛出 TimeoutError 异常。如果需要程序继续运行下去,就要用 try … except 捕捉和处理这个异常。
这个办法对其他用 async def 定义的方法的执行也是有效的。