gpt4 book ai didi

python - 如何将父变量传递给python中的子进程?

转载 作者:太空宇宙 更新时间:2023-11-03 12:20:57 24 4
gpt4 key购买 nike

我正在尝试让父 python 脚本将变量发送到子脚本,以帮助我加速和自动化视频分析。

我现在正在使用 subprocess.Popen() 调用来启动子脚本的 6 个实例,但无法找到一种方法将已在父级中调用的变量和模块传递给子级.例如,父文件将具有:

import sys
import subprocess
parent_dir = os.path.realpath(sys.argv[0])
subprocess.Popen(sys.executable, 'analysis.py')

然后 import sys;导入子流程; parent_dir 必须在“analysis.py”中再次调用。有没有办法把它们传给 child ?

简而言之,我想要实现的是:我有一个包含数百个视频文件的文件夹。我希望父 python 脚本列出视频文件并启动最多 6 个分析脚本的并行实例,每个实例分析一个视频文件。如果没有更多文件要分析,则父文件停止。

最佳答案

这里的简单答案是:不要使用 subprocess.Popen,使用 multiprocessing.Process .或者,更好的是 multiprocessing.Poolconcurrent.futures.ProcessPoolExecutor .

使用subprocess,您程序的Python 解释器根本不知道有关子进程的任何信息;就其所知,子进程正在运行 Doom。所以没有办法直接与它共享信息。*但是通过 multiprocessing,Python 控制启动子进程并设置所有内容,以便您可以尽可能方便地共享数据。

不幸的是,“尽可能方便”仍然不是 100% 像在一个过程中那样方便。但你能做的通常已经足够好了。阅读有关 Exchanging objects between processes 的部分以及以下几个部分;希望其中一种机制正是您所需要的。

但是,正如我在顶部暗示的那样,在大多数情况下,您可以通过使用池使它变得更简单。与其考虑“运行 6 个进程并与它们共享数据”,不如将其视为“在 6 个进程的池上运行一堆任务”。任务基本上只是一个函数——它接受参数并返回一个值。如果您想要并行化的工作适合该模型——听起来就像您的工作一样——生活就会尽可能简单。例如:

import multiprocessing
import os
import sys

import analysis

parent_dir = os.path.realpath(sys.argv[0])

paths = [os.path.join(folderpath, file)
for file in os.listdir(folderpath)]

with multiprocessing.Pool(processes=6) as pool:
results = pool.map(analysis.analyze, paths)

如果您使用的是 Python 3.2 或更早版本(包括 2.7),则不能在 with 语句中使用 Pool。我相信你想要这个:**

pool = multiprocessing.Pool(processes=6)
try:
results = pool.map(analysis.analyze, paths)
finally:
pool.close()
pool.join()

这将启动 6 个进程,*** 然后告诉第一个执行 analysis.analyze(paths[0]),第二个执行 analysis.analyze(paths[ 1]) 等。只要任何进程完成,池就会为它提供下一个工作路径。当它们全部完成后,您会得到所有结果的列表。****

当然,这意味着必须将 analysis.py 中的顶层代码移动到函数 def analyze(path): 中,这样您就可以调用它。或者,更好的是,如果您真的想保存该 import 行,您可以将该函数移动到主脚本中,而不是单独的文件中。


* 您仍然可以间接共享信息,例如,将其编码为某种交换格式(如 JSON)并通过 stdin/stdout 管道、文件、共享内存段、套接字等,但 multiprocessing 有效地将其包装起来,让您更轻松。

** 有多种方法可以关闭池,您也可以选择是否立即加入,所以您真的应该在某个时候阅读详细信息。但是当您所做的只是调用 pool.map 时,这真的无关紧要;当 map 调用返回时,池保证关闭并几乎立即准备好加入。

*** 我不确定你为什么想要 6;大多数机器有 4、8 或 16 个内核,而不是 6 个;为什么不全部使用它们呢?最好的做法通常是完全省略 processes=6 并让 multiprocessing 询问您的操作系统要使用多少个内核,这意味着它仍会运行在新机器上全速运行,内核数量是您明年购买的两倍。

**** 这有点过于简单了;通常池会给第一个进程一批文件,而不是一次一个,以节省一些开销,如果您需要优化事物或更仔细地排序它们,您可以手动控制批处理。但通常你不在乎,这种过度简化是可以的。

关于python - 如何将父变量传递给python中的子进程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29601087/

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