fork()如何/为什么会失败

时间:2013-11-14 23:39:48

标签: c posix

我正在研究C中的fork()函数。我理解它的作用(我认为)。我的问题是为什么我们在以下程序中检查它?

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
  int pid;
  pid=fork();

  if(pid<0)/* why is this here? */
  {
    fprintf(stderr, "Fork failed");
    exit(-1);
  }
  else if (pid == 0)
  {
    printf("Printed from the child process\n");
  }
  else
  {
    printf("Printed from the parent process\n");
    wait(pid);
  }
}

在这个程序中,我们检查返回的PID是否为&lt; 0,表示失败。为什么fork()会失败?

5 个答案:

答案 0 :(得分:18)

从手册页:

 Fork() will fail and no child process will be created if:
 [EAGAIN]           The system-imposed limit on the total number of pro-
                    cesses under execution would be exceeded.  This limit
                    is configuration-dependent.

 [EAGAIN]           The system-imposed limit MAXUPRC (<sys/param.h>) on the
                    total number of processes under execution by a single
                    user would be exceeded.

 [ENOMEM]           There is insufficient swap space for the new process.

(这是来自OS X手册页,但其他系统的原因相似。)

答案 1 :(得分:12)

fork可能失败,因为你生活在现实世界中,而不是一些无限递归的数学幻想世界,因此资源是有限的。特别地,sizeof(pid_t)是有限的,并且这使得在fork可能成功的次数(没有任何进程终止)的情况下,256 ^ sizeof(pid_t)的硬上限。除此之外,您还有其他资源需要担心内存。

答案 2 :(得分:2)

可能没有足够的内存来制作新流程。

答案 3 :(得分:1)

如果内核无法分配内存,那就非常糟糕,会导致fork()失败。

在这里查看错误代码:

http://linux.die.net/man/2/fork

答案 4 :(得分:1)

显然,由于以下因素,它可能会失败(不是真正的失败,而是无限地挂起):

  1. 尝试配置一些代码
  2. 许多线程
  3. 很多内存分配

另请参见

https://github.com/jvm-profiling-tools/async-profiler/issues/97

https://github.com/gperftools/gperftools/issues/704

https://bugzilla.redhat.com/show_bug.cgi?id=645528

示例:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main()
{
    size_t sz = 32*(size_t)(1024*1024*1024);
    char *p = (char*)malloc(sz);
    memset(p, 0, sz);
    fork();
    return 0;
}

内部版本:

gcc -pg tmp.c

运行:

./a.out