如何选择 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 与字典一起工作?

如何用 ProcessPoolExecutor 优雅地终止 loop.run_in_executor?

ProcessPoolExecutor 和 Ctrl C