问题
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
etclower the resources required by the
fork
-ing program. In particular, lower the heap memory requirementsincrease 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