Too many child with fork() [duplicate]

天大地大妈咪最大 提交于 2019-12-20 07:41:31

问题


The code :

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);
                };
    }
}

My problem is that i get too many child (nbenfant = 24), i got much more than 24 :/

This is my 3rd post today here but still not solved :(

Thanks


回答1:


Read carefully the fork(2) man page. Read that page several times, it is hard to understand. Read also the wikipage on fork (system call) and on processes (computing).

Please understand -and that takes time- that fork is returning simultaneously twice on success: once in the parent and once in the child

The fork syscall can fail (and then returns -1) for a number of reasons. On failure of fork please use perror or some other way to show the errno. And you should always keep the result of fork. So code

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;
    }

In particular, fork can fail because

   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.

If you want to be able to fork more processes, try to:

  • increase the RLIMIT_NPROC resource limit with setrlimit(2) (which might be called by system facilities, so look also into /etc/pam.d/login etc

  • lower the resources required by the fork-ing program. In particular, lower the heap memory requirements

  • increase some system resources, like perhaps swap. You could swapon some temporary file for testing.

As Joachim Pileborg replied you should avoid forking too much (the forked process continues the loop so is also forking again).

Don't forget that stdio routines are buffered. Use fflush(3) appropriately.

I suggest reading the Advanced Linux Programming book (available online) which has a full chapter explaining process handling on Linux.

BTW, check with ps or top or pstree how many processes you have (and with the free command how much memory is used, but read http://linuxatemyram.com/ before complaining). It could happen that your particular system is not able to fork more than 24 times your particular program (because of lack of resources)

Study also the source code of simple shells (like sash) and use strace -f (e.g. on some shell, or on your program) to understand more what syscalls are done. Also learn how to use the gdb debugger.




回答2:


It's because each child continues with the loop and so in turn fork their own children. When the children are done, you should either return from the main function or call exit.




回答3:


The child process coutinue fork new child process, you just need stop it .

Like this:

 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);
            };
    }
}


来源:https://stackoverflow.com/questions/18549411/too-many-child-with-fork

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!