【问题标题】:How should I use asyncio in a library without interfering with other callers?我应该如何在库中使用 asyncio 而不会干扰其他调用者?
【发布时间】:2015-11-27 12:34:16
【问题描述】:

我想编写一个使用 asyncio 管理子进程的库。我不想强迫我的调用者自己异步,所以我更愿意得到一个new_event_loop,做一个run_until_complete,然后是close。理想情况下,我希望这样做不会与调用者可能正在做的任何其他异步操作发生冲突。

我的问题是等待子进程不起作用,除非你调用set_event_loop,它附加了内部观察者。但当然,如果我这样做,我可能会与调用者中的其他事件循环发生冲突。一种解决方法是缓存调用者的当前循环(如果有),然后在我完成恢复调用者的状态后再次调用set_event_loop。这几乎行得通。但是如果调用者不是 asyncio 用户,调用 get_event_loop 的副作用是我现在创建了一个以前不存在的全局循环,如果程序退出而不调用 @987654327,Python 将打印一个可怕的警告@ 在那个循环上。

我能想到的唯一元解决方法是执行一个关闭全局循环的atexit.register 回调。这不会与调用者发生冲突,因为 close 可以安全地多次调用,除非调用者做了一些疯狂的事情,比如在退出期间尝试启动全局循环。所以还是不完美。

有没有完美的解决方案?

【问题讨论】:

    标签: python python-asyncio


    【解决方案1】:

    您要实现的目标与ProcessPoolExecutor 非常相似(在concurrent.futures 中)。

    异步调用者:

    @coroutine
    def in_process(callback, *args, executor=ProcessPoolExecutor()):
        loop = get_event_loop()
        result = yield from loop.run_in_executor(executor, callback, *args)
        return result
    

    同步调用者:

    with ProcessPoolExecutor() as executor:
        future = executor.submit(callback, *args)
        result = future.result()
    

    【讨论】:

    • 这不是一个坏主意,现在我想知道使用线程而不是与 asyncio 搏斗对我来说是否更容易。但同时,分叉一个子进程感觉有点像放弃:(
    • @JackO'Connor 我认为坚持使用asyncio 可能是个好主意。它即将成为python中异步编程的新标准,尤其是python 3.5中引入了新的async and await keywords。我最近阅读了a very good article,它解释了为什么线程不好,而微线程也一样坏。我觉得在单个主线程中显式协程,通过 PoolExecutor 对线程和进程进行特定处理是最干净的解决方案。
    猜你喜欢
    • 2012-06-05
    • 2016-01-22
    • 1970-01-01
    • 2011-12-15
    • 1970-01-01
    • 2021-12-27
    • 2019-05-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多