用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上的进程处理。

顺便说一句,请检查pstoppstree你有多少进程(并使用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); }; } }