如何选择 ProcessPoolExecutor 进程的 python 解释器?
Posted
技术标签:
【中文标题】如何选择 ProcessPoolExecutor 进程的 python 解释器?【英文标题】:How to choose the python interpreter of a ProcessPoolExecutor process? 【发布时间】:2022-01-06 08:37:03 【问题描述】:我正在制作一个在 ProcessPoolExecutor 中运行进程并在完成后返回结果的程序。我要运行的脚本使用了相当旧的库,所以我不想将它们包含在主脚本中。相反,我设置了另一个虚拟环境来运行子进程。
我正在使用 ProcessPoolExecutor 来生成作业。在运行这些作业时如何选择要使用的 python 解释器?
我看到 ProcessPoolExecutor 有一个 initargs
参数,但是当我将它包含在我的代码中时:
with concurrent.futures.ProcessPoolExecutor(
initargs=('PYTHONHOME', r'C:\Users\Tom.Mclean\Anaconda3\envs\weatherrouting_v1')) as pool:
return await loop.run_in_executor(pool, fn, *args)
它刚刚崩溃了。
编辑:
with concurrent.futures.ProcessPoolExecutor() as pool:
pool._mp_context.set_executable(r'C:\Users\Tom.Mclean\Anaconda3\envs\weatherrouting_v2\python.exe')
return await loop.run_in_executor(pool, fn, *args)
【问题讨论】:
initargs
用于initializer
函数。两者都在过程开始后使用,因此它们不适合您想要做的事情。
@MisterMiyagi 嗯,看来我想要的相当于 multiprocessing.set_executable()
函数,有没有 ProcessPoolExecutor
的等价函数?
在某种程度上,是的。您可以为ProcessPoolExecutor
提供带有自定义可执行文件的multiprocessing
上下文。但是,我只是在 CPython 3.9 到 PyPy 3.7 上进行了尝试——启动进程有效,但 concurrent.futures
的部分不同足以立即破坏。
@MisterMiyagi 我对我的问题所做的编辑对我有用,对你有用吗?
它只有在两个 Python 都与主进程兼容时才有效'concurrent.futures
。因此,如果您有另一个相同 Python 版本的 venv 但很可能不是跨 Python 版本,它会起作用。
【参考方案1】:
为池提供具有显式可执行文件的multiprocessing
上下文。
import multiprocessing
import concurrent.futures
if __name__ == "__main__":
context = multiprocessing.get_context('spawn')
context.set_executable(...) # <<< set worker executable
with concurrent.futures.ProcessPoolExecutor(mp_context=context) as pool:
...
请注意,concurrent.futures
根据父进程的 concurrent.futures
库初始化工作进程。这意味着可执行文件必须能够在父进程'版本中解析和运行库。
因此,这可以例如与使用相同 Python 版本的不同 venv 一起使用。它不能用于运行明显较旧的 Python 版本,例如 Python 3.9 的父进程和 Python 3.7 的工作进程。
【讨论】:
以上是关于如何选择 ProcessPoolExecutor 进程的 python 解释器?的主要内容,如果未能解决你的问题,请参考以下文章
如何使 ProcessPoolExecutor 中的任务表现得像守护进程?
如何使用 asyncio 和 concurrent.futures.ProcessPoolExecutor 在 Python 中终止长时间运行的计算(CPU 绑定任务)?
如何使用 asyncio 和 concurrent.futures.ProcessPoolExecutor 在 Python 中终止长时间运行的计算(CPU 绑定任务)?
如何让 concurrent.futures ProcessPoolExecutor 与字典一起工作?