【问题标题】:Python event loop does not work properly with stdinPython 事件循环不能与标准输入一起正常工作
【发布时间】:2019-10-14 10:50:54
【问题描述】:

我正试图了解 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 帮助我理解这种行为

【问题讨论】:

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


    【解决方案1】:

    您在第一次设置中不正确地使用了 asyncio。您不需要在线程模块中插入它。

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

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

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

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

    【讨论】:

    • 1.我认为在与主线程不同的线程中运行事件循环是完全合法和有效的。如果我们不希望从循环中返回结果,我们可以将任务推入其中并让它们运行(就像我正在做的那样)。此外,如果它有问题,第二个示例也不应该运行,因为它也使用在单独的线程中运行的相同循环。
    • 2.我也试过你的建议。我在async def main() 中移动了while 循环代码,并像这样从主线程运行它。 event_loop.run_until_complete(main())。还是不行
    猜你喜欢
    • 2011-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-16
    • 2022-06-13
    • 2020-09-07
    相关资源
    最近更新 更多