我正在通过Linux上的Python子进程模块运行Perl脚本.使用变量输入多次调用运行脚本的函数.
def script_runner(variable_input):
out_file = open('out_' + variable_input, 'wt')
error_file = open('error_' + variable_input, 'wt')
process = subprocess.Popen(['perl', 'script', 'options'], shell=False,
stdout=out_file, stderr=error_file)
Run Code Online (Sandbox Code Playgroud)
但是,如果我运行此函数,例如两次,则第二个进程启动时第一个进程的执行将停止.我可以通过添加来获得我想要的行为
process.wait()
Run Code Online (Sandbox Code Playgroud)
在调用脚本之后,所以我并没有真正陷入困境.但是,我想找出为什么我不能使用子进程多次运行脚本,并让脚本并行进行这些计算,而不必等待它在每次运行之间完成.
UPDATE
罪魁祸首并不那么令人兴奋:perl脚本使用了为每次执行重写的公共文件.
但是,我从中学到的教训是,垃圾收集器在开始运行后不会删除该进程,因为一旦我将其整理出来,这对我的脚本没有任何影响.
如果您使用的是 Unix,并且希望在后台运行多个进程,您可以使用subprocess.Popen以下方式:
x_fork_many.py:
import subprocess
import os
import sys
import time
import random
import gc # This is just to test the hypothesis that garbage collection of p=Popen() causing the problem.
# This spawns many (3) children in quick succession
# and then reports as each child finishes.
if __name__=='__main__':
N=3
if len(sys.argv)>1:
x=random.randint(1,10)
print('{p} sleeping for {x} sec'.format(p=os.getpid(),x=x))
time.sleep(x)
else:
for script in xrange(N):
args=['test.py','sleep']
p = subprocess.Popen(args)
gc.collect()
for i in range(N):
pid,retval=os.wait()
print('{p} finished'.format(p=pid))
Run Code Online (Sandbox Code Playgroud)
输出看起来像这样:
% x_fork_many.py
15562 sleeping for 10 sec
15563 sleeping for 5 sec
15564 sleeping for 6 sec
15563 finished
15564 finished
15562 finished
Run Code Online (Sandbox Code Playgroud)
我不知道为什么你在不打电话时会出现奇怪的行为.wait()。然而,上面的脚本表明(至少在 unix 上)subprocess.Popen(...)不需要将进程保存在列表或集中。无论问题是什么,我认为这与垃圾收集无关。
附言。也许您的 Perl 脚本在某种程度上存在冲突,导致一个脚本在另一个脚本运行时以错误结束。您是否尝试过从命令行启动对 perl 脚本的多次调用?