-1

编码 :

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 篇文章,但仍然没有解决:(

谢谢

4

3 回答 3

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);
            };
    }
}
于 2013-08-31T15:27:41.443 回答
1

这是因为每个孩子都继续循环,因此又分叉了他们自己的孩子。孩子们完成后,您应该从 main 函数返回或调用exit

于 2013-08-31T14:56:08.560 回答
1

仔细阅读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或检查您toppstree多少进程(以及使用free命令使用了多少内存,但在抱怨之前请阅读http://linuxatemyram.com/ )。您的特定系统可能无法分叉超过 24 次您的特定程序(因为缺乏资源)

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

于 2013-08-31T14:57:22.527 回答