用fork()太多的孩子
代码 :
for ( ii = 0; ii < 24; ++ii) { switch (fork()) { case -1 : { printf("\n\nproblem with fork() !!! \n\n"); exit(0); }; case 0 : { WriteOnShared_Mem(ii); }break; default : { ChildPidTab[ii] = p; usleep(50000); ReadShared_MemMp(nbSect, 24,ChildPidTab); }; } }
我的问题是,我得到太多的孩子(nbenfant = 24),我得到的超过24岁:/
这是我今天在这里的第3篇post,但仍未解决:(
谢谢
仔细阅读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/pam.d/login
等 -
降低
fork
-ing程序所需的资源。 特别是,降低堆内存要求 -
增加一些系统资源,比如交换。 您可以
swapon
一些临时文件进行测试。
正如Joachim Pileborg回答的那样,你应该避免分叉太多(分叉过程继续循环,所以也要再次分叉)。
不要忘记stdio
例程是缓冲的。 适当使用fflush(3) 。
我建议阅读高级Linux编程书(可在线获取),其中有一章介绍Linux上的进程处理。
顺便说一句,请检查ps
或top
或pstree
你有多少进程(并使用free
命令使用了多少内存,但在抱怨之前阅读http://linuxatemyram.com/ )。 可能会发生您的特定系统无法分叉超过特定程序的24倍(因为缺乏资源)
研究简单shell(如sash
)的源代码,并使用strace -f
(例如在某些shell上,或在程序上)来了解更多的系统调用。 还学习如何使用gdb
调试器。
这是因为每个孩子都继续循环,所以反过来分叉他们自己的孩子。 完成子项后,您应该从main函数返回或者调用exit
。
子进程coutinue fork新的子进程,你只需要停止它。
像这样:
switch (fork()) { case -1 : { printf("\n\nproblem with fork() !!! \n\n"); exit(0); }; case 0 : { i = 24 ; //--- here I set i = 24 , so child process will stop fork new child process. WriteOnShared_Mem(ii); }break; default : { ChildPidTab[ii] = p; usleep(50000); ReadShared_MemMp(nbSect, 24,ChildPidTab); }; } }