仔细阅读fork(2) 手册页。把那页读了好几遍,很难理解。另请阅读 fork (system call) 和 processes (computing) 上的维基页面。
请理解 - 这需要时间 - fork 在成功时同时返回两次:一次在父项中,一次在子项中
fork 系统调用可能因多种原因而失败(然后返回 -1)。如果fork 失败,请使用perror 或其他方式显示errno。您应该始终保留fork 的结果。所以代码
for (ii = 0; ii < 24; ++ii) {
fflush(NULL);
pid_t p = fork();
switch (p) {
case -1 : // fork failed
printf("\n\nproblem with fork() in pid %d error %s!!! \n\n",
(int) getpid(), strerror(errno));
exit(EXIT_FAILURE);
break;
case 0: // child process
WriteOnShared_Mem(ii);
ii = MAX_INT; // to stop the for loop
break;
default: // parent process
ChildPidTab[ii] = p;
/// etc.... some synchronization is needed
break;
}
特别是,fork 可能会失败,因为
EAGAIN fork() cannot allocate sufficient memory to copy the
parent's page tables and allocate a task structure for
the child.
EAGAIN It was not possible to create a new process because the
caller's RLIMIT_NPROC resource limit was encountered. To
exceed this limit, the process must have either the
CAP_SYS_ADMIN or the CAP_SYS_RESOURCE capability.
ENOMEM fork() failed to allocate the necessary kernel structures
because memory is tight.
如果您希望能够分叉更多进程,请尝试:
使用setrlimit(2) 增加RLIMIT_NPROC 资源限制(可能由系统设施调用,因此还要查看/etc/pam.d/login 等
降低fork-ing 程序所需的资源。特别是降低堆内存要求
增加一些系统资源,比如交换。你可以swapon一些临时文件进行测试。
作为Joachim Pileborg replied,你应该避免分叉太多(分叉的进程继续循环,所以也再次分叉)。
不要忘记stdio 例程被缓冲。适当使用fflush(3)。
我建议阅读Advanced Linux Programming 的书(可在线获得),其中有一整章解释了 Linux 上的进程处理。
顺便说一句,使用ps 或top 或pstree 检查您有多少进程(以及使用free 命令使用了多少内存,但在抱怨之前请阅读http://linuxatemyram.com/)。您的特定系统可能无法 fork 超过 24 次特定程序(因为缺乏资源)
还要研究简单 shell 的源代码(例如 sash)并使用 strace -f(例如在某些 shell 上或在您的程序上)来了解更多系统调用的作用。还学习如何使用gdb 调试器。