Python事件循环无法与stdin一起正常使用

时间:2019-05-28 21:16:14

标签: python python-3.x python-asyncio event-loop

我正在努力让我了解python的asyncio。我写了这段代码只是为了演示,以弄清楚概念。

import asyncio
import threading


async def printer(b, a):
    print(b)
    await asyncio.sleep(5)
    print(a)


def loop_runner(loop):
    print('[RUNNING LOOP]')
    loop.run_forever()


if __name__ == '__main__':
    event_loop = asyncio.get_event_loop()
    # run_forever() is blocking. running it from separate thread
    loop_thread = threading.Thread(target=loop_runner, args=(event_loop,))
    loop_thread.start()

    while True:
        before, after = input('Before :'), input('After :')
        event_loop.create_task(printer(before, after))

我正在从单独的线程运行事件循环,并尝试在运行时循环创建任务。但是我不明白为什么这段代码不起作用。它需要输入,但是直接进行下一次迭代,而无需打印printer函数中的任何内容。

令人惊讶的是,如果我不接受stdin的输入,而只使用像这样的硬编码消息

   messages = [('Hello', 'world'), ('Foo', 'bar'), ('Alice', 'Bob')]

    for message in messages:
        before, after = message
        coroutine = printer(f'[ITERATION] {count} [MESSAGE] {before}', f'[ITERATION] {count} [MESSAGE] {after}')
        event_loop.create_task(coroutine)
        count += 1

一切正常。输出

[RUNNING LOOP]
[ITERATION] 0 [MESSAGE] Hello
[ITERATION] 1 [MESSAGE] Foo
[ITERATION] 2 [MESSAGE] Alice
[ITERATION] 0 [MESSAGE] world
[ITERATION] 1 [MESSAGE] bar
[ITERATION] 2 [MESSAGE] Bob

请帮助我通过input

了解这种行为

1 个答案:

答案 0 :(得分:1)

您在第一个设置中未正确使用asyncio。您不需要将其与线程模块插入。

为此,我建议的设置是创建一个异步函数主程序,该主程序包含一个无限循环,您可以在其中请求输入并创建任务。然后,您可以在声明完之后从事件循环中运行main。

提醒您,等待您在上述设置中的main内部创建的任务是可选的;由于可以保证内核可以同步stdout(我确定是70%,这是真的),因此您可以一次运行任意数量的任务来运行printer()。但是,如果您确实等待任务,则用户尝试输入时不会打印出程序。它会先调用printer(),它首先写入stdout,然后仅在printer()完成后要求下一组输入。

希望能回答您的问题。请参阅以下文档作为其他资源。

https://docs.python.org/3/library/asyncio-task.html