OS X 杀死太快分叉的进程?
OS X Kills processes that fork too quickly?
我是操作系统 class 的助教,学生们的任务是开发 fork bomb defuser。作为测试用例的一部分,我想开发一些看起来像叉子炸弹但实际上相当安全的东西(即产生许多进程,但这些进程被删除)。我的问题是,在我的 OS X 机器上测试它时,我注意到如果我将 usleep 延迟设置得太低(~100000)并且 children 的数量太高,它实际上会杀死我所有的用户进程(~1000)。当我说全部时,我指的是 Firefox、Xcode、Word,甚至 Finder 似乎都出现故障。这对我来说似乎有点奇怪,因为任务只有一个 child,但我想知道 OS X 是否对用户可以拥有的 child 进程数有限制。我在 google 上找不到任何内容,但欢迎提出任何建议。
特别是:
1) 这段代码是否不合理,我错过了一些应该被杀死的明显原因?
2) OS X 中是否有一些文档可以解释我们看到此行为的原因?
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
int main(int argc, char **argv)
{
int i;
pid_t pid;
if(argc < 2) {
printf("Usage: fork_safe n\n");
return 0;
}
int n = strtol(argv[1], NULL, 10);
for(i = 0; i < n; i++) {
pid = fork();
if(pid == 0){
break;
} else {
printf("child pid %d, killing...\n", pid);
usleep(10000);
kill(pid,SIGTERM);
fflush(stdout);
}
}
while(1);
return 0;
}
您没有检查 fork()
中的 return 值是否有误。如果它 returns -1
,则您将 -1 传递给 kill
函数。
并且根据man page for the kill function:
If pid equals -1, then sig is sent to every process for which the
calling process has permission to send signals, except for process 1
(init), but see below.
所以我怀疑 fork
在无法分配更多进程时失败了。因此,您的代码正在向您帐户拥有的每个进程发送一个 SIGTERM。这解释了您所看到的行为。
相应地修改您的 for 循环:
for(i = 0; i < n; i++)
{
pid = fork();
if(pid == 0)
{
break;
}
else if (pid == -1)
{
printf("Unable to allocate any more processes\n");
return 0;
}
else
{
printf("child pid %d, killing...\n", pid);
usleep(10000);
kill(pid,SIGTERM);
fflush(stdout);
}
}
我是操作系统 class 的助教,学生们的任务是开发 fork bomb defuser。作为测试用例的一部分,我想开发一些看起来像叉子炸弹但实际上相当安全的东西(即产生许多进程,但这些进程被删除)。我的问题是,在我的 OS X 机器上测试它时,我注意到如果我将 usleep 延迟设置得太低(~100000)并且 children 的数量太高,它实际上会杀死我所有的用户进程(~1000)。当我说全部时,我指的是 Firefox、Xcode、Word,甚至 Finder 似乎都出现故障。这对我来说似乎有点奇怪,因为任务只有一个 child,但我想知道 OS X 是否对用户可以拥有的 child 进程数有限制。我在 google 上找不到任何内容,但欢迎提出任何建议。
特别是: 1) 这段代码是否不合理,我错过了一些应该被杀死的明显原因? 2) OS X 中是否有一些文档可以解释我们看到此行为的原因?
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
int main(int argc, char **argv)
{
int i;
pid_t pid;
if(argc < 2) {
printf("Usage: fork_safe n\n");
return 0;
}
int n = strtol(argv[1], NULL, 10);
for(i = 0; i < n; i++) {
pid = fork();
if(pid == 0){
break;
} else {
printf("child pid %d, killing...\n", pid);
usleep(10000);
kill(pid,SIGTERM);
fflush(stdout);
}
}
while(1);
return 0;
}
您没有检查 fork()
中的 return 值是否有误。如果它 returns -1
,则您将 -1 传递给 kill
函数。
并且根据man page for the kill function:
If pid equals -1, then sig is sent to every process for which the calling process has permission to send signals, except for process 1 (init), but see below.
所以我怀疑 fork
在无法分配更多进程时失败了。因此,您的代码正在向您帐户拥有的每个进程发送一个 SIGTERM。这解释了您所看到的行为。
相应地修改您的 for 循环:
for(i = 0; i < n; i++)
{
pid = fork();
if(pid == 0)
{
break;
}
else if (pid == -1)
{
printf("Unable to allocate any more processes\n");
return 0;
}
else
{
printf("child pid %d, killing...\n", pid);
usleep(10000);
kill(pid,SIGTERM);
fflush(stdout);
}
}