fork, childs, zombies, start a process in the background without waiting for it

Discussion in 'Perl Misc' started by Rex Gustavus Adolphus, Jul 1, 2003.

  1. Hi

    I have a parent program, that should loop (eternally), and start other
    programs without waiting for them, so many programs can be started at
    the same time by the parent.

    Is it true that it's not necessary to handle childsignals if you use
    this type of logic when you fork processes:

    if ($pid = fork) {
    # parent
    } elsif (defined $pid) {
    # child
    exec $agent
    or die "Can't do $agent";
    } else {
    # fork error
    die "can't fork\n";
    }
    Rex Gustavus Adolphus, Jul 1, 2003
    #1
    1. Advertising

  2. (Greg Bacon) wrote in message news:<>...
    > In article <>,
    > Rex Gustavus Adolphus <> wrote:
    >
    > : I have a parent program, that should loop (eternally), and start other
    > : programs without waiting for them, so many programs can be started at
    > : the same time by the parent.
    >
    > Careful not to create a forkbomb. :)
    >
    > : Is it true that it's not necessary to handle childsignals if you use
    > : this type of logic when you fork processes:
    > :
    > : if ($pid = fork) {
    > : # parent
    > : } elsif (defined $pid) {
    > : # child
    > : exec $agent
    > : or die "Can't do $agent";
    > : } else {
    > : # fork error
    > : die "can't fork\n";
    > : }
    >
    > According to the perlipc manpage, it might even be easier, depending
    > on your surroundings:
    >
    > On most Unix platforms, the CHLD (sometimes also known
    > as CLD) signal has special behavior with respect to a
    > value of 'IGNORE'. Setting $SIG{CHLD} to 'IGNORE' on
    > such a platform has the effect of not creating zombie
    > processes when the parent process fails to wait() on
    > its child processes (i.e. child processes are
    > automatically reaped). Calling wait() with $SIG{CHLD}
    > set to 'IGNORE' usually returns -1 on such platforms.
    >
    > Greg


    Thanks Greg!
    But I'm sorry I don't understand if your answer means that the
    fork-logic code I provided above is OK, so the parent doesn't have to
    wait for the childs to avoid zombies?
    Could you please clarify?
    I like this to be as portable as possible so I'm a bit wary of the
    'most' in 'On most Unix platforms...'
    (On the Linux i tried, it said 'Can't ignore signal CHLD, forcing to
    default.')

    RGA
    Rex Gustavus Adolphus, Jul 2, 2003
    #2
    1. Advertising

  3. bob niederman <> wrote in message news:<3f026252_1@127.0.0.1>...
    > Greg Bacon wrote:
    > > In article <>,
    > > Rex Gustavus Adolphus <> wrote:
    > >
    > > : I have a parent program, that should loop (eternally), and start other
    > > : programs without waiting for them, so many programs can be started at
    > > : the same time by the parent.
    > >
    > > Careful not to create a forkbomb. :)

    >
    > Not a fork-bomb because exec doesn't return.
    >
    > W/ perl 5.8.0 on Linux (rh9.0) I couldn't seem to create zobies w/ exec.
    >
    > With proccesses that ran perl and exited, I had zombies if I didn't
    > waitpid on them, but only while the parent was up - once the parent
    > finished, the zombie children went away too. YMMV on other perl/OS
    > combinations.
    >


    Thanks Bob,
    but since my parent should keep running, I _must_ avoid leaving
    zombies around.

    I think I found the solution in PerlFAQ 8.12: "double fork"
    (I must admit I thougt my previous method was "double fork" but I now
    realize it isn't):
    You immediately wait() for your first child, and the init daemon will
    wait() for your grandchild once it exits.

    unless ($pid = fork) {
    unless (fork) {
    exec "what you really wanna do";
    die "exec failed!";
    }
    exit 0;
    }
    waitpid($pid,0);


    BTW, whats "YMMV"?
    /RGA
    Rex Gustavus Adolphus, Jul 2, 2003
    #3
  4. Rex Gustavus Adolphus

    Greg Bacon Guest

    In article <>,
    Rex Gustavus Adolphus <> wrote:

    : Thanks Greg!

    Glad to help.

    : But I'm sorry I don't understand if your answer means that the
    : fork-logic code I provided above is OK, so the parent doesn't have to
    : wait for the childs to avoid zombies?
    : Could you please clarify?

    Assuming your platform exhibits that behavior, i.e., autoreaping
    kids when you ignore SIGCHLD.

    : I like this to be as portable as possible so I'm a bit wary of the
    : 'most' in 'On most Unix platforms...'
    : (On the Linux i tried, it said 'Can't ignore signal CHLD, forcing to
    : default.')

    If you want portability, good ol' double-fork is the way to go.

    Greg
    --
    FDR ran on a platform of cutting expenditures by 25 percent, ending deficits,
    reducing federal salaries, assuring a sound currency, protecting states
    rights, and keeping the peace. And when he governed, he did exactly the
    opposite. -- Lew Rockwell
    Greg Bacon, Jul 2, 2003
    #4
  5. Re: fork, childs, zombies, start a process in the background withoutwaiting for it

    Rex Gustavus Adolphus wrote:

    > BTW, whats "YMMV"?


    "Your Mileage May Vary"; i.e., it works for me, but I don't guarantee it'll
    work for you.

    Chris Mattern
    Chris Mattern, Jul 2, 2003
    #5
  6. (Rex Gustavus Adolphus) wrote:

    > I think I found the solution in PerlFAQ 8.12: "double fork"
    > (I must admit I thougt my previous method was "double fork" but I now
    > realize it isn't):
    > You immediately wait() for your first child, and the init daemon will
    > wait() for your grandchild once it exits.
    >
    > unless ($pid = fork) {
    > unless (fork) {
    > exec "what you really wanna do";
    > die "exec failed!";
    > }
    > exit 0;
    > }
    > waitpid($pid,0);
    >
    >


    Hi, back again...

    Now I tried double forking, and that seems to work in simple
    testscripts,
    but when I used it in my real app, witch involves DBI to connect
    to an Oracle-database, my grandparent loses the db-connection as soon
    as the grandparent spawns kids and grandkids (the grandkids connects
    to the same database, but I'm not sending any db-handles to the kids
    or anything like that).

    (I have not yet been able to figure out at what exact moment the
    grandparent loses it's db-connection)

    I quote from "Programming Perl": "File descriptors ... are shared,
    while everything else is copied--or at least made to look that way."

    What does this mean?

    If I have:
    my $dbh = ${&db_connect()};
    in the forking program
    is $dbh copied to the kids and therefore dropped when the kids dies?




    Anyway, now I'm trying this method instead, it seems to work:

    # found something to do:
    system("what I really wanna do &"); # NB the '&' at the end

    # I can keep on immediately, because of the '&' above
    # doing more system-calls if needed


    Simple!
    No forking, no waiting, no zombies, no hassles!

    Why didn't I do this from the beginning?


    Is there any disadvantage?
    Anything I'm missing?

    /RGA
    Rex Gustavus Adolphus, Jul 4, 2003
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Luigi
    Replies:
    5
    Views:
    404
    Donn Cave
    Apr 3, 2006
  2. Knute Johnson
    Replies:
    2
    Views:
    702
    Mark Space
    Aug 15, 2008
  3. Replies:
    0
    Views:
    2,748
  4. bitcycle
    Replies:
    3
    Views:
    426
    Nobody
    Jul 7, 2011
  5. Iñaki Baz Castillo

    How to know the childs PID of a given process?

    Iñaki Baz Castillo, Jan 4, 2010, in forum: Ruby
    Replies:
    5
    Views:
    114
    Iñaki Baz Castillo
    Jan 4, 2010
Loading...

Share This Page