gpt4 book ai didi

python - asyncio.to_thread() 方法与 ThreadPoolExecutor 不同吗?

转载 作者:行者123 更新时间:2023-12-04 14:44:31 26 4
gpt4 key购买 nike

我看到 @python 3.9+ 添加了 asyncio.to_thread() 方法,它的描述说它在单独的线程上运行阻塞代码以立即运行。见下面的例子:

def blocking_io():
print(f"start blocking_io at {time.strftime('%X')}")
# Note that time.sleep() can be replaced with any blocking
# IO-bound operation, such as file operations.
time.sleep(1)
print(f"blocking_io complete at {time.strftime('%X')}")

async def main():
print(f"started main at {time.strftime('%X')}")

await asyncio.gather(
asyncio.to_thread(blocking_io),
asyncio.sleep(1))

print(f"finished main at {time.strftime('%X')}")


asyncio.run(main())

# Expected output:
#
# started main at 19:50:53
# start blocking_io at 19:50:53
# blocking_io complete at 19:50:54
# finished main at 19:50:54
通过解释,它似乎使用线程机制而不是上下文切换或协程。这是否意味着它实际上并不是异步的?它与concurrent.futures.ThreadPoolExecutor中的传统多线程相同吗?那么这样使用线程有什么好处呢?

最佳答案

Source codeto_thread很简单。归结为等待run_in_executor使用默认执行程序(执行程序参数是 None ),即 ThreadPoolExecutor .
事实上,是的,这是传统的多线程,旨在运行在单独线程上的代码不是异步的,而是 to_thread允许您await其结果是异步的。
另请注意,该函数在当前任务的上下文中运行,因此其 context variable值将在 func 中可用.

async def to_thread(func, /, *args, **kwargs):
"""Asynchronously run function *func* in a separate thread.
Any *args and **kwargs supplied for this function are directly passed
to *func*. Also, the current :class:`contextvars.Context` is propogated,
allowing context variables from the main thread to be accessed in the
separate thread.
Return a coroutine that can be awaited to get the eventual result of *func*.
"""
loop = events.get_running_loop()
ctx = contextvars.copy_context()
func_call = functools.partial(ctx.run, func, *args, **kwargs)
return await loop.run_in_executor(None, func_call)

关于python - asyncio.to_thread() 方法与 ThreadPoolExecutor 不同吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65316863/

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