farnham@spot.Colorado.EDU (Farnham David) (05/16/91)
I'm having trouble getting rid of processes which I've killed. I have a situation where the main program calls a function which fork()'s and exec()'s. This function returns the pid of the child to the main program. The main program then kill()'s this child. I don't seem to have any problem killing the child, but after several iterations I run out of process space and I can no longer fork(). Could someone please shed some light on what I'm doing wrong. Mild flames are tolerable if I'm doing something REALLY stupid :-) Using: Sun sparc 2, 4.1.1 Code follows: ---------------------------------------- #include <stdio.h> /* this is main() and fun() */ #include <signal.h> int fun(); main() { int pid; while (1) { pid = fun(); sleep(1); if ((kill(pid,SIGKILL)) == -1) { fprintf (stderr,"Kill failed\n"); exit(1); } } } int fun() { int pid; switch(pid = fork()) { case -1: fprintf (stderr,"Can't fork\n"); break; case 0: execl("./tst","tst",(char *)NULL); fprintf (stderr,"Can't exec\n"); break; default: return pid; } } ---------------------------------------- #include <stdio.h> /* this is tst.c */ main() { puts ("in tst"); while (1) ; } ---------------------------------------- Dave Farnham Ball Aerospace Electro-Optical/Cryogenics Division P.O. Box 1062 Boulder, CO 80306 { farnham@spot.colorado.edu, farnham@handel.cs.colostate.edu }
subbarao@phoenix.Princeton.EDU (Kartik Subbarao) (05/16/91)
In article <1991May15.201821.15350@colorado.edu> farnham@spot.Colorado.EDU (Farnham David) writes: >I'm having trouble getting rid of processes which I've killed. >I have a situation where the main program calls a function which >fork()'s and exec()'s. This function returns the pid of the >child to the main program. The main program then kill()'s this child. > >I don't seem to have any problem killing the child, but after several >iterations I run out of process space and I can no longer fork(). >Could someone please shed some light on what I'm doing wrong. Mild >flames are tolerable if I'm doing something REALLY stupid :-) Most likely, the reason why you're running out of process space is because you don't wait() for your children. You can kill your children 'till you're blue in the face, and it won't help any. That's because when a process dies, it becomes a zombie until someone waits for it. This means that it takes up a space in the process table, though it's really not doing anything. It's a simple fix: > > while (1) { > pid = fun(); > sleep(1); > if ((kill(pid,SIGKILL)) == -1) { > fprintf (stderr,"Kill failed\n"); > exit(1); > } wait(0); /* add this line in */ > } Of course, if you're actually INTERESTED in what the kid returns, then you should look at wait(2) to find out more variations on wait. -Kartik -- internet% ypwhich subbarao@phoenix.Princeton.EDU -| Internet kartik@silvertone.Princeton.EDU (NeXT mail) SUBBARAO@PUCC.BITNET - Bitnet
weimer@garden.ssd.kodak.com (Gary Weimer (253-7796)) (05/16/91)
In article <azA8awz/XVBkw@idunno.Princeton.EDU>, subbarao@phoenix.Princeton.EDU (Kartik Subbarao) writes: |> In article <1991May15.201821.15350@colorado.edu> farnham@spot.Colorado.EDU (Farnham David) writes: |> >I'm having trouble getting rid of processes which I've killed. |> >I have a situation where the main program calls a function which |> >fork()'s and exec()'s. This function returns the pid of the |> >child to the main program. The main program then kill()'s this child. |> > |> >I don't seem to have any problem killing the child, but after several |> >iterations I run out of process space and I can no longer fork(). |> >Could someone please shed some light on what I'm doing wrong. Mild |> >flames are tolerable if I'm doing something REALLY stupid :-) |> |> Most likely, the reason why you're running out of process space is because |> you don't wait() for your children. You can kill your children 'till you're |> blue in the face, and it won't help any. That's because when a process |> dies, it becomes a zombie until someone waits for it. This means that it |> takes up a space in the process table, though it's really not doing |> anything. It's a simple fix: |> |> > |> > while (1) { |> > pid = fun(); |> > sleep(1); |> > if ((kill(pid,SIGKILL)) == -1) { |> > fprintf (stderr,"Kill failed\n"); |> > exit(1); |> > } |> wait(0); /* add this line in */ |> > } Is this all that's wrong with vi in SunOS??? Doing: vi !}fmt :r!ps produces (extras left out): PID TT STAT TIME COMMAND 4262 p5 S 0:00 vi 4263 p5 Z 0:00 <defunct> ^^^^^^^^^ With one of these for each shell run from within vi. Gets anoying when your process table gets full... weimer@ssd.kodak.com ( Gary Weimer )
gwyn@smoke.brl.mil (Doug Gwyn) (05/17/91)
In article <1991May15.201821.15350@colorado.edu> farnham@spot.Colorado.EDU (Farnham David) writes: >I don't seem to have any problem killing the child, but after several >iterations I run out of process space and I can no longer fork(). Sure -- processes continue to occupy slots in the process table, and thus are counted against your process limit, until they are successfully wait()ed on. Kill()ing them just makes zombies out of the processes; wait() lays them to rest.
gt0178a@prism.gatech.EDU (BURNS) (05/26/91)
in article <16177@smoke.brl.mil>, gwyn@smoke.brl.mil (Doug Gwyn) says: > In article <1991May15.201821.15350@colorado.edu> farnham@spot.Colorado.EDU (Farnham David) writes: >>I don't seem to have any problem killing the child, but after several >>iterations I run out of process space and I can no longer fork(). > Sure -- processes continue to occupy slots in the process table, > and thus are counted against your process limit, until they are > successfully wait()ed on. Kill()ing them just makes zombies out > of the processes; wait() lays them to rest. If the SIG_DFL for SIGCHLD is to discard the signal, why do you HAVE to wait for the child? The only time I've had to wait under HP-UX for a child is to guard against *transient* peaks of numbers of children - they would eventually die anyway. Is this a SYSV/BSD diff? Thanx. -- BURNS,JIM (returned student & Technology Dynamics staff member, an ATDC co.) Georgia Institute of Technology, 30178 Georgia Tech Station, Atlanta Georgia, 30332 | Internet: gt0178a@prism.gatech.edu uucp: ...!{decvax,hplabs,ncar,purdue,rutgers}!gatech!prism!gt0178a
gwyn@smoke.brl.mil (Doug Gwyn) (05/27/91)
In article <29877@hydra.gatech.EDU> gt0178a@prism.gatech.EDU (BURNS) writes: >If the SIG_DFL for SIGCHLD is to discard the signal, why do you HAVE to >wait for the child? I can't speak for HP-UX, but in general SIGCHLD/SIGCLD is pretty badly botched. In the original System V implementation, how you set SIGCLD also determines the semantics for a subsequent wait() system call. All I can suggest is (a) leave SIGCLD alone, and (b) if you're trying to use SIGCLD anyway, check the SPECIFIC system manual and be very careful. In good old original UNIX, the only way to get rid of a zombie was to wait() on it, and if its parent terminated, then init (Process #1) would inherit it and IT would wait() on it.
mouse@thunder.mcrcim.mcgill.edu (der Mouse) (05/30/91)
In article <1991May15.215826.26327@athena.mit.edu>, jik@athena.mit.edu (Jonathan I. Kamens) writes: > You need to wait on your children to get them to go away; until you > do that, they're zombies. > Here's my occasionally posted article about that: > Unfortunately, it's impossible to generalize how the death of child > processes should behave, because the exact mechanism varies over the > various flavors of Unix. [...] If you just want to fork children, don't want them to bother you when they die, don't care about preserving precise parenthood relationships, and don't care about the return status from the wait or resource usage or anything of the sort, you *can* do *that* portably. All you need to do is fork and have the parent wait for the child explicitly, then have the child fork again, with the second-level child doing the real work and the first-level child dying immediately after the second fork. This way, the parent has no children left, because its only child exited. When the intermediate process died, init (PID 1) inherited the second child and will worry about doing the wait() when it dies. Not that this is always appropriate, but sometimes it is. der Mouse old: mcgill-vision!mouse new: mouse@larry.mcrcim.mcgill.edu