仔细阅读fork(2)手册页。把那页读了好几遍,很难理解。另请阅读关于fork(系统调用)和进程(计算)的 wikipage 。
请理解 - 这需要时间 -成功时同时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/etc/pam.d/login
降低fork
-ing 程序所需的资源。特别是降低堆内存要求
增加一些系统资源,比如交换。您可以swapon
使用一些临时文件进行测试。
正如Joachim Pileborg 回答的那样,您应该避免分叉太多(分叉进程继续循环,因此也再次分叉)。
不要忘记stdio
例程是缓冲的。适当地使用fflush(3)。
我建议阅读Advanced Linux Programming一书(可在线获得),其中有一整章解释了 Linux 上的进程处理。
顺便说一句,检查ps
或检查您top
有pstree
多少进程(以及使用free
命令使用了多少内存,但在抱怨之前请阅读http://linuxatemyram.com/ )。您的特定系统可能无法分叉超过 24 次您的特定程序(因为缺乏资源)
还要研究简单 shell 的源代码(如sash
)并使用strace -f
(例如,在某些 shell 上或在您的程序上)以了解更多系统调用的作用。还学习如何使用gdb
调试器。