OS X杀死过快的进程?

时间:2016-03-14 20:54:27

标签: macos operating-system fork osx-elcapitan

我是操作系统课程的助教,其中学生的任务是开发fork bomb defuser。作为测试用例的一部分,我想开发一些看起来像叉子炸弹的东西,但实际上相当安全(即产生许多过程,但这些过程被删除)。我的问题是,在我的OS X机器上进行测试时,我注意到如果我将usleep延迟设置得太低(~100000)并且子项数量太高(~1000),它实际上会杀死我的所有用户进程。当我说所有我的意思是Firefox,Xcode,Word,甚至Finder似乎都会失败。这对我来说有点奇怪,因为任务只有一个孩子,但我想知道OS X是否对用户可以拥有的子进程数有限制。我无法在谷歌上找到任何东西,但任何建议都表示赞赏。

特别是: 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;
}

1 个答案:

答案 0 :(得分:3)

您没有检查fork()的返回值是否有错误。如果它返回-1,则您将-1传递给kill函数。

根据man page for the kill function

  

如果pid等于-1,则将sig发送到每个进程   调用进程有权发送信号,但进程1除外   (init),但见下文。

因此我怀疑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);
    }
}
相关问题