gpt4 book ai didi

python - asyncio.run_in_executor 是否指定不明确?

转载 作者:太空狗 更新时间:2023-10-29 21:53:59 36 4
gpt4 key购买 nike

我有一个服务器应用程序,当客户请求时,我会安排一些工作,比如

def work():
time.sleep(5)

fut = asyncio.get_event_loop().run_in_executor(None, work)

await fut 稍后当明确请求时。我的用例要求 run_in_executor 立即提交 work 函数,这在我的环境(Ubuntu 16.04、Python 3.7.1)中的表现符合预期。

由于我的应用程序依赖于此行为,所以我想验证它不会发生变化,因此我检查了几个资源:

  1. documentation似乎有点模糊。 awaitable 似乎它可能适用于方法或返回值 - 尽管文本正文确实说它显式返回 asyncio.Future
  2. PEP 3156指定 asyncio - 这里它没有说 run_in_executor 是协程。
  3. 在一些问题中,run_in_executor 是返回可等待对象的函数还是协程本身似乎被视为实现细节。参见 2567532327 .
  4. AbstractEventLoop.run_in_executor被指定为协程,但在BaseEventLoop.run_in_executor中实现是一个简单的函数。

1 和 2 似乎主要表明当前行为是正确的,但 3 和 4 是令人担忧的。这似乎是接口(interface)的一个非常重要的部分,因为如果函数本身是协程,那么它不会开始执行(因此不会安排工作)直到它被等待。

依赖当前行为是否安全?如果是这样,将 AbstractEventLoop.run_in_executor 的接口(interface)改为普通函数而不是协程是否合理?

最佳答案

My use case requires that run_in_executor submit the work function immediately, and that behaves as expected in my environment

documentation 不保证当前行为 ,它只指定函数 arrangesfunc 调用,并且它返回一个 awaitable。如果它是用协程实现的,它将在事件循环运行之前不会提交。

但是,此行为自 the beginning 以来一直存在并且在未来极不可能改变。延迟提交,尽管文档在技术上允许,但会破坏许多现实世界的异步应用程序,并构成严重的向后不兼容的更改。

如果您想确保任务启动时不依赖于未记录的行为,您可以创建自己的等同于 run_in_executor 的函数。真的boils down结合executor.submitasyncio.wrap_future .没有多余的装饰,它可以像这样简单:

def my_run_in_executor(executor, f, *args):
return asyncio.wrap_future(executor.submit(f, *args))

因为函数中直接调用了executor.submit,所以这个版本保证了worker函数的启动,而无需等待事件循环运行。

PEP 3156明确声明 run_in_executor 是“等同于 wrap_future(executor.submit(callback, *args))”,从而提供所需的保证——但 PEP 不是官方文档,最终的实现和规范通常与最初的 PEP 不同。

如果坚持使用 run_in_executor 的文档化接口(interface),也可以使用显式同步来强制协程等待 worker 启动:

async def run_now(f, *args):
loop = asyncio.get_event_loop()
started = asyncio.Event()
def wrapped_f():
loop.call_soon_threadsafe(started.set)
return f(*args)
fut = loop.run_in_executor(None, wrapped_f)
await started.wait()
return fut

fut = await run_now(work)
# here the worker has started, but not (necessarily) finished
result = await fut
# here the worker has finished and we have its return value

这种方法引入了不必要的实现和接口(interface)复杂性,特别是需要使用 await 来获得 future,这与 asyncio 的正常工作方式背道而驰。 run_now 仅用于完整性目的,我不建议在生产中使用它。

关于python - asyncio.run_in_executor 是否指定不明确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54263558/

36 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com