太多的孩子用叉子()

时间:2013-08-31 14:52:52

标签: c 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篇帖子,但仍未解决:(

由于

3 个答案:

答案 0 :(得分:1)

这是因为每个孩子都继续循环,因此依次分叉他们自己的孩子。孩子完成后,您应该从主要功能返回或致电exit

答案 1 :(得分:1)

仔细阅读 fork(2)手册页。多次阅读该页面,很难理解。另请阅读fork (system call)processes (computing)上的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程序所需的资源。特别是,降低堆内存要求

  • 增加一些系统资源,比如交换。你可以swapon一些临时文件进行测试。

作为Joachim Pileborg replied你应该避免分叉太多(分叉的过程会继续循环,所以也会再次分叉)。

不要忘记缓存stdio个例程。适当使用fflush(3)

我建议阅读Advanced Linux Programming书籍(在线提供),其中有一章全面介绍了Linux上的流程处理。

BTW,请检查pstoppstree您有多少进程(以及free命令使用了多少内存,但请阅读{{3在抱怨之前)。可能会发生您的特定系统无法分叉超过您特定程序的24倍(因为缺乏资源)

还要研究简单shell的源代码(如sash)并使用strace -f(例如在某些shell或程序上)来了解更多系统调用的功能。还要了解如何使用gdb调试器。

答案 2 :(得分:1)

子进程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);
            };
    }
}