bash - 长时间运行的 bash 脚本导致可用 PID 的资源泄漏

标签 bash scripting memory-leaks

我目前正在阅读有关 Bash 脚本尤其是进程管理的更多详细信息 here 。在“PID 和父级”部分中,我发现了以下声明:

A process's PID will NEVER be freed up for use after the process dies UNTIL the parent process waits for the PID to see whether it ended and retrieve its exit code.

所以,如果我理解正确的话,如果我在 bash 脚本中启动一个进程,那么该进程就会终止,PID 不能被任何其他进程使用。这是否意味着,如果我有一个长时间运行的脚本,它重复启动其他子进程但从不等待它们,我最终会出现资源泄漏,因为使用的 PID 不会返回到系统?

如果我实际上等待其他进程,但等待被陷阱取消了,怎么样?这种等待会以某种方式释放 PID,还是在捕获陷阱后我必须再次等待?

最佳答案

幸运的是你不会。我不能告诉你确切的原因,但你可以很容易地测试一下。运行以下脚本(使用 Ctrl+C 停止):

#!/bin/bash

while true; do
    sleep 5 &
    sleep 1
done

你可以看到你没有得到zombies (PID 泄露)6 秒以上。要查看一些僵尸,请使用以下 python 代码(再次使用 Ctrl+C 停止):

#!/usr/bin/python
import subprocess, time

pl = []
while True:
    pl.append(subprocess.Popen(["sleep", "5"]))
    time.sleep(1)

6 秒后你会看到一只僵尸:

ps xaw | grep 'sleep'
...
26470 pts/2    Z+     0:00 [sleep] <defunct>
...

我的猜测是 bash 确实 wait并存储使用或不使用内置 wait 命令获取僵尸进程的结果。对于 python 脚本,如果删除 pl.append 部分,垃圾收集就会释放对象,并再次神奇地收获僵尸。仅供引用, child 可能永远不会成为僵尸(来自维基百科,Zombie process):

...if the parent explicitly ignores SIGCHLD by setting its handler to SIG_IGN (rather than simply ignoring the signal by default) or has the SA_NOCLDWAIT flag set, all child exit status information will be discarded and no zombie processes will be left.

关于bash - 长时间运行的 bash 脚本导致可用 PID 的资源泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11032743/

相关文章:

bash - 如何打印一个零填充的整数给定宽度?

接受多个参数的 Bash CLI

linux - 从文件中读取用户名和密码

ios - 使用 Objective-C block 时避免泄漏的最佳做法是什么?

c - 从 C# 代码访问 C 代码中分配的结构体内存

bash - 将 cpu 温度的平均值作为一行脚本获取

arrays - 如何将字符串转换为 BASH 数组?

python - 运行csh脚本时让python输入密码

jquery 文档在外部脚本中准备就绪

ios - NSString 的内存管理问题