Question on fork(), exec(), kill()

Question on fork(), exec(), kill()

Post by Farnham Dav » Fri, 17 May 1991 05:18:21



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

Quote:}

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

Quote:}

----------------------------------------
#include <stdio.h>  /* this is tst.c */

main()
{
    puts ("in tst");
    while (1)
        ;

Quote:}

----------------------------------------

Dave Farnham
Ball Aerospace
Electro-Optical/Cryogenics Division
P.O. Box 1062
Boulder, CO  80306

 
 
 

Question on fork(), exec(), kill()

Post by Kartik Subbar » Fri, 17 May 1991 09:30:23



>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:

Quote:

>    while (1) {
>        pid = fun();
>        sleep(1);
>        if ((kill(pid,SIGKILL)) == -1) {
>            fprintf (stderr,"Kill failed\n");
>            exit(1);
>        }

                 wait(0); /* add this line in */

Quote:>     }

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





 
 
 

Question on fork(), exec(), kill()

Post by Gary Weimer (253-77 » Fri, 17 May 1991 23:47:32




|> >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...


 
 
 

Question on fork(), exec(), kill()

Post by Doug Gw » Sat, 18 May 1991 13:16:49



>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.
 
 
 

Question on fork(), exec(), kill()

Post by BURN » Mon, 27 May 1991 16:55:45




>>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,

uucp:     ...!{decvax,hplabs,ncar,purdue,rutgers}!gatech!prism!gt0178a
 
 
 

Question on fork(), exec(), kill()

Post by Doug Gw » Tue, 28 May 1991 12:14:47



>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.

 
 
 

Question on fork(), exec(), kill()

Post by Jonathan I. Kame » Fri, 17 May 1991 06:58:26


  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.  Perhaps someone who's "in the know" (or at
least more so than I am) about POSIX can tell us what the POSIX standard
behavior (if there is any) for this is.

  First of all, by default, you have to do a wait() for child processes
under ALL flavors of Unix.  That is, there is no flavor of Unix that I
know of that will automatically flush child processes that exit, even if
you don't do anything to tell it to do so.

  Second, allegedly, under some SysV-derived systems, if you do
"signal(SIGCHLD, SIG_IGN)", then child processes will be cleaned up
automatically, with no further effort in your part.  However, people
have told me that they've never seen this actually work; the best way to
find out if it works at your site is to try it, although if you are
trying to write portable code, it's a bad idea to rely on this in any case.

  If you can't use SIG_IGN to force automatic clean-up, then you've got
to write a signal handler to do it.  It isn't easy at all to write a
signal handler that does things right on all flavors of Unix, because of
the following inconsistencies:

  On some flavors of Unix, the SIGCHLD signal handler is called if one
*or more* children have died.  This means that if your signal handler
only does one wait() call, then it won't clean up all of the children.
Fortunately, I believe that all Unix flavors for which this is the case
have available to the programmer the wait3() call, which allows the
WNOHANG option to check whether or not there are any children waiting to
be cleaned up.  Therefore, on any system that has wait3(), your signal
handler should call wait3() over and over again with the WNOHANG option
until there are no children left to clean up.

  On SysV-derived systems, SIGCHLD signals are regenerated if there are
child processes still waiting to be cleaned up after you exit the
SIGCHLD signal handler.  Therefore, it's safe on most SysV systems to
assume when the signal handler gets called that you only have to clean
up one signal, and assume that the handler will get called again if
there are more to clean up after it exits.

  On older systems, signal handlers are automatically reset to SIG_DFL
when the signal handler gets called.  On such systems, you have to put
"signal(SIGCHILD, catcher_func)" (where "catcher_func" is the name of
the handler function) as the first thing in the signal handler, so that
it gets reset.  Unfortunately, there is a race condition which may cause
you to get a SIGCHLD signal and have it ignored between the time your
handler gets called and the time you reset the signal.  Fortunately,
newer implementations of signal() don't reset the handler to SIG_DFL
when the handler function is called.

  The summary of all this is that on systems that have wait3(), you
should use that and your signal handler should loop, and on systems that
don't, you should have one call to wait() per invocation of the signal
handler.  Also, if you want to be 100% safe, the first thing your
handler should do is reset the handler for SIGCHLD, even though it isn't
necessary to do this on most systems nowadays.

--
Jonathan Kamens                               USnail:
MIT Project Athena                              11 Ashford Terrace

Office: 617-253-8085                          Home: 617-782-0710

 
 
 

Question on fork(), exec(), kill()

Post by der Mou » Fri, 31 May 1991 19:20:25



Quote:> 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

 
 
 

1. fork/exec question - killing child when parent dies

I have a C program in which I fork, then exec a
child process.  The parent process does not wait
for the child process to finish and continues on
it's way.  If the parent process dies for whatever
reason, I want to kill the child process.  I know
that if the child process dies, a SIGCHLD signal
would be sent to the parent, but is there a way
to notify the child process if the parent dies?

Thanks,

Chris

2. Looking for advice on price of DiskonChip 2000 Gang Programmer

3. system(command) = fork + exec(command)? kill parent, children?

4. Nonblocking socket can't connect to a server

5. Efficiency: fork() w/ shared libraries vs. fork()/exec()

6. Gosling likes idea of open source Java (Re: More as* kicking: Unilever picks J2EE over .NET)

7. General Fork()/Exec()/System() Call Question

8. Connect to a console from serial port

9. fork/exec question

10. Q: fork() & exec() question

11. fork-exec-socket questions

12. *A fork/exec/wait question