简体   繁体   English

尽管调用了subprocess.Popen.wait(),由Python的子进程模块创建的进程是否仍有可能用完内存(是僵尸)?

[英]Is it possible that processes created by subprocess module in Python still use up memory (are zombies), although subprocess.Popen.wait() was called?

According to the answers to another question in stackoverflow ( how to kill (or avoid) zombie processes with subprocess module ) one can avoid zombie processes by using the command subprocess.Popen.wait() . 根据stackoverflow中另一个问题的答案( 如何使用子进程模块杀死(或避免)僵尸进程 ),可以使用命令subprocess.Popen.wait()避免僵尸进程。

However, when I run the following function perform_sth inside my script a several thousand times, the memory usage of each individual process tends to increase: 但是,当我在脚本中运行以下函数perform_sth几千次时,每个进程的内存使用量往往会增加:

For example, the first process only needs 7 MB, but nr. 例如,第一个进程仅需要7 MB,但是仅需7 MB。 1000 already 500 MB, until in the end more than 8 GB are used and I have to kill the whole Python script. 1000已经有500 MB,直到最后使用了超过8 GB,我必须杀死整个Python脚本。 The process should always use more or less the same amount of memory. 该进程应始终使用或多或少相同数量的内存。

Probably I have a flaw in my function and need to additionally kill the processes? 可能我的功能存在缺陷,是否需要额外终止进程?

My code is: 我的代码是:

def perform_sth(arg1, arg2):
    import subprocess


    sth_cline = ["sth", "-asequence=%s"%arg1, "-bsequence=%s"]
    process = subprocess.Popen(
                                sth_cline, 
                                stdout = subprocess.PIPE, 
                                stderr = subprocess.PIPE
                                )
    process.wait()
    return 

Do not use stdout=PIPE if you don't read from the pipe. 如果您不从管道读取数据,请不要使用stdout=PIPE

Your child process is not zombie (a zombie is a dead process; it needs only a tiny amount of memory, to store its exit status in the process table). 您的子进程不是僵尸 (僵尸是一个死进程;它只需要很少的内存,即可将其退出状态存储在进程表中)。 Your child process is alive (that is why it is capable of consuming gigabytes of memory). 您的子进程仍处于活动状态 (这就是为什么它能够消耗千兆字节的内存)。

The OS pipe buffer is probably full and the child process is blocked while trying to write to the pipe. 尝试写入管道时,操作系统管道缓冲区可能已满,并且子进程被阻塞。 Your parent should drain the buffer by reading from the pipe to allow the child to continue but the parent waits for process.wait() to return forever (a deadlock). 您的父级应该通过从管道中读取来耗尽缓冲区,以允许子级继续运行,但是父级等待process.wait()永远返回(死锁)。

If you don't need the output, use stdout=subprocess.DEVNULL instead. 如果不需要输出,请改用stdout=subprocess.DEVNULL Or see How to hide output of subprocess in Python 2.7 或参阅如何在Python 2.7中隐藏子流程的输出

#!/usr/bin/env python
from subprocess import check_call, DEVNULL, STDOUT

check_call(["sth", "arg 1", "arg2"], stdin=DEVNULL, stdout=DEVNULL, stderr=STDOUT)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM