为什么我必须使用.wait()和python的子进程模块?

Vik*_*mma 6 python subprocess

我正在通过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脚本使用了为每次执行重写的公共文件.

但是,我从中学到的教训是,垃圾收集器在开始运行后不会删除该进程,因为一旦我将其整理出来,这对我的脚本没有任何影响.

unu*_*tbu 2

如果您使用的是 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 脚本的多次调用?