Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/299.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在python中如何将父进程中的变量传递给子进程?_Python_Subprocess - Fatal编程技术网

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

在python中如何将父进程中的变量传递给子进程?,python,subprocess,Python,Subprocess,我试图让父python脚本将变量发送给子脚本,以帮助我加快并自动化视频分析 我现在使用subprocess.Popen()调用来启动子脚本的6个实例,但无法找到将父脚本中已调用的变量和模块传递给子脚本的方法。例如,父文件将具有: import sys import subprocess parent_dir = os.path.realpath(sys.argv[0]) subprocess.Popen(sys.executable, 'analysis.py') 然后导入系统;导入子流程;必

我试图让父python脚本将变量发送给子脚本,以帮助我加快并自动化视频分析

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

import sys
import subprocess
parent_dir = os.path.realpath(sys.argv[0])
subprocess.Popen(sys.executable, 'analysis.py')
然后
导入系统;导入子流程;必须在“analysis.py”中再次调用parent_dir
。有没有办法把它们传给孩子


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

这里的简单答案是:不要使用
subprocess.Popen
,使用。或者,更好的是,
多处理.Pool

使用
子进程
,程序的Python解释器对子进程一无所知;据它所知,子进程正在运行厄运。因此无法直接与它共享信息。*但是通过
多处理
,Python控制启动子流程并设置所有设置,以便您可以尽可能方便地共享数据

不幸的是,“尽可能方便”并不像所有流程都在一个过程中那样方便。但是你所能做的通常是足够好的。阅读上的章节和以下几个章节;希望其中一种机制正是您所需要的

但是,正如我在顶部所暗示的,在大多数情况下,您可以通过使用池使其更加简单。与其考虑“运行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 = multiprocessing.Pool(processes=6)
try:
    results = pool.map(analysis.analyze, paths)
finally:
    pool.close()
    pool.join()
这将启动6个进程,***然后告诉第一个进程执行
分析。分析(路径[0])
,第二个进程执行
分析。分析(路径[1])
,等等。一旦任何进程完成,池将为其提供下一条工作路径。当它们全部完成时,你会得到一个所有结果的列表****

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


*您仍然可以通过以下方式间接共享信息:例如,将其封送为JSON等交换格式,并通过stdin/stdout管道、文件、共享内存段、套接字等进行传递,但
多处理
有效地将其包装起来,使之更加容易

**关闭一个池有不同的方法,您也可以选择是否立即加入,因此您确实应该在某个时候仔细阅读详细信息。但是,当您所做的只是调用
pool.map
时,这其实并不重要;当
map
调用返回时,该池保证会立即关闭并准备好加入

***我不知道你为什么想要6;大多数机器有4个、8个或16个磁芯,而不是6个;为什么不全部使用呢?最好的做法通常是完全忽略
进程=6
,让
多处理
询问您的操作系统要使用多少内核,这意味着它仍将在新机器上全速运行,内核数量是您明年购买的两倍


****这有点过于简单化;通常,池将为第一个进程提供一批文件,而不是一次一个,以节省一点开销,如果需要优化或更仔细地排序,您可以手动控制批处理。但通常情况下,你并不在意,这种过于简单化的做法很好。

哇,谢谢你给出了快速而详尽的答案。我已经很久没有使用python了,这就是我需要帮助的原因。我的分析脚本大约有50行代码用于设置,150行用于视频的实际分析。我可以简单地将50行移到主脚本中,并从您那里了解到我可以从150行创建一个函数来分析视频,然后运行多处理命令来同时运行多个循环,对吗?无论何时一个视频完成,它都会转到下一个文件,直到到达路径的末尾。关于进程数,我只是试图找到最佳进程数,以便在最短的时间内分析所有视频。我有一个强大的MacMini,有4个内核,通过在不同的终端窗口中运行多个分析脚本进行测试,我发现6个在分析的总nr帧/时间方面效果最好。但是,关于进程的nr,您有一个很好的观点。我怎样才能让“多重处理”决定我同时运行多少个进程?再次感谢您的大力帮助@JolJols:首先,对于第二个问题:只需执行
多处理.Pool()
,而不是
多处理.Pool(processes=6)
,它就会询问操作系统,实际上这意味着它调用了
OS.cpu\u count()
,我认为这与您从
sysctl hw.ncpu
得到的结果相同,可能是4。我的猜测是6胜4,因为您在I/O而不是CPU上花费了大量时间(因此您可以有4个co)