我正在使用Python 3.4.3。当我的事件循环正在工作时,我正在与一些无限过程进行通信(示例中为tail -f
)。完成所有其他任务后,我也会取消tail
任务,等待它完成并关闭循环。
import asyncio
import time
@asyncio.coroutine
def tailf():
try:
create = asyncio.create_subprocess_exec(
'tail', '-f', '/tmp/file',
stdout=asyncio.subprocess.PIPE,
)
proc = yield from create
while True:
l = yield from proc.stdout.readline()
print(l)
except BaseException as e:
print('CAUGHT', type(e))
@asyncio.coroutine
def task():
yield from asyncio.sleep(1)
loop = asyncio.get_event_loop()
tailf_task = loop.create_task(tailf())
loop.run_until_complete(asyncio.wait([task()]))
tailf_task.cancel()
loop.run_until_complete(asyncio.wait([tailf_task]))
loop.close()
输出结果为:
b'123\n'
CAUGHT <class 'concurrent.futures._base.CancelledError'>
Exception ignored in: Exception ignored in:
在运行示例之前,请echo 123 > /tmp/file
获得相同的结果。
除了我在剧本结尾处收到警告外,一切都按预期工作。
我认为原因是yield from proc.stdout.readline()
被中断了,但我想在那种情况下抓住例外。
所以,问题是:我做错了什么?
更广泛的一个:下次如何调试此类警告?
答案 0 :(得分:0)
取消与tail -f
通信的协程后,它应该终止进程并等待它结束(查看except
):
@asyncio.coroutine
def tailf():
try:
create = asyncio.create_subprocess_exec(
'tail', '-f', '/tmp/file',
stdout=asyncio.subprocess.PIPE,
)
proc = yield from create
while True:
l = yield from proc.stdout.readline()
print(l)
except asyncio.CancelledError:
proc.terminate()
yield from proc.wait()
您在Python 3.6中没有收到警告,但仍然会在进程列表中挂起未终结的tail -f
。