我曾经使用过HP-UX系统,老管理员告诉我,系统上的僵尸进程数量有上限,我相信是1024。
- 这是一个困难的事实上限吗?我认为您可以拥有任意数量的僵尸,就像可以拥有任意数量的进程一样……?
- 发行版与发行版之间是否有不同的价值?
- 如果我们达到上限并尝试创建另一个僵尸会发生什么?
ulimit -u
。有一段时间我很困惑,因为man ulimit
我没有提到C例程-u
。提到的ulimit实际上是内置的bash工具,在bash联机帮助页中对此进行了描述。
我曾经使用过HP-UX系统,老管理员告诉我,系统上的僵尸进程数量有上限,我相信是1024。
ulimit -u
。有一段时间我很困惑,因为man ulimit
我没有提到C例程-u
。提到的ulimit实际上是内置的bash工具,在bash联机帮助页中对此进行了描述。
Answers:
我没有可用的HP-UX,而且我从来都不是HP-UX的忠实拥护者。
看来在Linux上,存在多少子进程的每个进程或每个用户的限制。您可以使用limit
内置的Zsh 看到它(似乎类似于ulimit -u
bash中的代码):
1002 % limit
cputime unlimited
filesize unlimited
datasize unlimited
stacksize 8MB
coredumpsize 0kB
memoryuse unlimited
maxproc 16136
...
那是在一台Arch Linux笔记本电脑上。
我编写了一个小程序来测试该限制:
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
volatile int sigchld_cnt = 0;
voida
sigchld_hdlr(int signo)
{
++sigchld_cnt;
}
int
main(int ac, char **av)
{
int looping = 1;
int child_cnt = 0;
int status;
signal(SIGCHLD, sigchld_hdlr);
printf("Parent PID %d\n", getpid());
while (looping)
{
switch (fork())
{
case 0:
_exit(0);
break;
case -1:
fprintf(stderr, "Problem with fork(), %d children: %s\n",
child_cnt, strerror(errno));
looping = 0;
break;
default:
++child_cnt;
break;
}
}
fprintf(stderr, "Sleeping, forked %d child processes\n", child_cnt);
fprintf(stderr, "Received %d sigchild\n", sigchld_cnt);
sleep(10);
looping = 1;
do {
int x = wait(&status);
if (x != -1)
--child_cnt;
else if (errno != EINTR) {
fprintf(stderr, "wait() problem %d children left: \%s\n",
child_cnt, strerror(errno));
looping = 0;
}
} while (looping);
printf("%d children left, %d SIGCHLD\n", child_cnt, sigchld_cnt);
return 0;
}
通过调用wait(2)
足够的时间来“收集”所有僵尸是非常困难的。另外,接收到的SIGCHLD信号的数量与分叉的子进程的数量永远不会相同:我相信linux内核有时会为多个退出的子进程发送1 SIGCHLD。
无论如何,在我的Arch Linux笔记本电脑上,我得到了16088个子进程的分叉,并且必须是僵尸数量,因为该程序不会wait(2)
在信号处理程序中进行系统调用。
在Slackware 12服务器上,我得到6076个子进程,该子进程与的值非常匹配maxproc 6079
。我的用户ID还有2个其他正在运行的进程sshd
和Zsh。加上上面的第一个非僵尸程序实例,使6079。
该fork(2)
系统调用失败,出现“资源暂时不可用”错误。我看不到任何其他证据证明什么资源不可用。如果我同时在2个不同的xterm中运行程序,我会得到一些不同的数字,但是它们的总和与我在一个xterm中运行它的数字相同。我认为它是进程表条目,交换或某些系统范围的资源,而不仅仅是任意限制。
我现在没有其他可以尝试的功能。
我不知道HP-UX的限制是什么。但是我可以告诉您,逻辑实现是要有一个最大大小的进程表。理论上,进程表条目的总数受进程ID范围的限制,但是大多数实现对表的大小都有限制,从而产生的最大值要小得多。大多数Unix变体对每个用户的进程数也有限制。您可以通过ulimit -u
在bash中运行来查看限制。
我不希望UNIX系统对僵尸有单独的限制,而不是对进程ID(包括实际进程和僵尸)的数量没有单独的限制。因此,当进程死亡并成为僵尸时,这不会影响限制:在进程派生时分配资源(进程表中的条目),并在收获进程时释放资源。
我认为您可以拥有任意数量的僵尸,就像可以拥有任意数量的进程一样……?
僵尸进程最终是一个进程-在特殊状态下-然后僵尸进程受限于进程表的可用性和大小,就像常规进程一样。
发行版与发行版之间是否有不同的价值?
当然,还有其他许多参数。您不应该中继特定的大小,或者中继大小是否足以容纳许多僵尸进程。如果您有太多的僵尸,那么解决方案就不是大问题了,因为最终它会变得很满。僵尸进程本身并不坏,但是累积的僵尸进程过多则表明“行为不良”程序允许进行僵尸进程。
如果我们达到上限并尝试创建另一个僵尸会发生什么?
一旦进程表充满了常规和僵尸进程,就不能再创建新的常规进程,即使系统具有足够的资源(内存,处理器等)也是如此。唯一缺少的资源只是过程表中的单个条目。当已经在运行的程序(甚至那些“表现良好”的程序)需要创建子进程时,它们将开始失败。无法启动新程序,甚至无法运行单个命令。
Even running single commands would fail.
->影响很大。