python - 为什么我必须将 .wait() 与 python 的子进程模块一起使用?

标签 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)

但是,如果我运行这个函数,比方说,运行两次,第一个进程的执行将在第二个进程启动时停止。我可以通过添加

来获得我想要的行为
process.wait()

调用脚本后,我并没有真正卡住。但是,我想找出为什么我不能使用 subprocess 多次运行脚本,并让脚本并行进行这些计算,而不必在每次运行之间等待它完成。

更新

罪魁祸首并不那么令人兴奋:perl 脚本使用了一个为每次执行重写的公共(public)文件。

但是,我从中吸取的教训是,垃圾收集器不会在进程开始运行后删除它,因为一旦我整理好它,这对我的脚本没有任何影响。

最佳答案

如果您使用的是 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))

输出看起来像这样:

% 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

我不确定为什么您在不调用 .wait() 时会出现奇怪的行为。但是,上面的脚本建议(至少在 unix 上)不需要将 subprocess.Popen(...) 进程保存在列表或集合中。不管是什么问题,我认为这与垃圾回收无关。

附言。也许您的 perl 脚本在某种程度上存在冲突,这会导致一个脚本在另一个脚本运行时以错误结束。您是否尝试过从命令行启动对 perl 脚本的多次调用?

关于python - 为什么我必须将 .wait() 与 python 的子进程模块一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4165145/

相关文章:

python - threading.Thread 如何在 Python 中产生剩余的量子?

一段时间后python子进程变得空闲

python - 在 Python 中使用子进程

python - 在 os.system() 期间什么会导致 "IOError: [Errno 9] Bad file descriptor"?

python - 如何分组连接行,同时忽略列中的无值?

python - Celery UnicodeDecodeError 与 django

python - 如何返回每个分类实例的概率?

python - Django 服务构建有许多 MIME 类型错误(sveltekit)

python - 在 Django 中,如何调用启动时间较慢的子进程

batch-file - 从 .bat 文件非同步运行一系列命令