[英]How to run a blocking task asynchronously with ProcessPoolExecutor and asyncio?
我正在尝试使用 ProcessPoolExecutor 异步运行阻塞任务(它与 ThreadPoolExecutor 一起使用,但我需要 ProcessPoolExecutor 来执行 CPU 绑定任务)。 这是我的代码:
import asyncio
import time
from concurrent.futures import ProcessPoolExecutor
async def run_in_thread(task, *args):
with ProcessPoolExecutor() as process_pool:
loop = asyncio.get_event_loop()
result = await loop.run_in_executor(process_pool, task, *args)
return result
async def main_task():
while True:
await asyncio.sleep(1)
print("ticker")
async def main():
asyncio.create_task(main_task())
global blocking_task
def blocking_task():
time.sleep(5)
print("blocking task done!")
await run_in_thread(blocking_task)
if __name__ == "__main__":
asyncio.run(main())
我得到这个错误:
result = await loop.run_in_executor(process_pool, task, *args)
concurrent.futures.process.BrokenProcessPool: A process in the process pool was terminated abruptly while the future was running or pending.
我不明白问题出在哪里,有人可以帮助我吗? 我还想了解为什么它适用于 ThreadPoolExecutor 而不是 ProcessPoolExecutor
我期待代码打印:
ticker
ticker
ticker
ticker
ticker
blocking task done!
将 blocking_task 的定义移动到模块的外层。 正如脚本所示,此功能对其他进程不可见。 该函数的代码不会直接发送给其他进程,只会发送其名称。 另一个进程执行自己单独的脚本导入,但名称未在顶层定义。
这与您尝试将此脚本导入另一个脚本的逻辑相同。 假设此脚本位于名为 foo.py 的文件中。 在执行import foo
之后,没有名为foo.blocking_task
的函数,因此您将无法调用它。
如果您查看整个回溯,而不仅仅是最后一行,这会更清楚一点。
顺便说一句,在函数定义前面使用全局语句与将定义移到顶层不是一回事。 在您的脚本中,名称blocking_task
在 main() 函数实际运行之前在模块级别不存在(辅助进程从不运行)。 在下面的工作脚本中,名称blocking_task
在导入模块后立即存在。
import asyncio
import time
from concurrent.futures import ProcessPoolExecutor
async def run_in_thread(task, *args):
with ProcessPoolExecutor() as process_pool:
loop = asyncio.get_event_loop()
result = await loop.run_in_executor(process_pool, task, *args)
return result
async def main_task():
while True:
await asyncio.sleep(1)
print("ticker")
def blocking_task():
time.sleep(5)
print("blocking task done!")
async def main():
asyncio.create_task(main_task())
await run_in_thread(blocking_task)
if __name__ == "__main__":
asyncio.run(main())
这将打印出您所期望的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.