使用带有无限进程的{create_subprocess_exec`

时间:2018-04-11 16:04:35

标签: python python-asyncio

我正在使用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()被中断了,但我想在那种情况下抓住例外。

所以,问题是:我做错了什么?

更广泛的一个:下次如何调试此类警告?

1 个答案:

答案 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