magarwal has asked for the wisdom of the Perl Monks concerning the following question:

HI,
I am forking a child process from the main process.Then again forking another process from the child process, like,
while (1) { my $remote_paddr = accept(my $remote_socket, SERVER_SOCK); if (!defined(my $pid = fork)) { die "cannot fork: $!"; } elsif ($pid) { next; } # Do some processing, my $myserver = DBIx::MyServer::DBI->new( socket => $remote_socket, dbh => $dbh, banner => $0.' '.join(' ', @ARGV)); # Now launching another child process as, while(1){ if (!defined(my $pid = fork)) { die "cannot fork: $!"; } elsif ($pid) { next; } # Do some processing, # exit second child process _exit(0); } # Exiting the first child process exit; }


When I exit the second child process, it closes the socket handle as well (or exiting the parent process as well).

What is the correct way to fork a child process and to exit it.And what I am doing wrong here.
Let me know your inputs.

Replies are listed 'Best First'.
Re: Killing a child process, kills parent process
by zentara (Cardinal) on Oct 13, 2011 at 17:00 UTC
      Is completely statifactory to reap all children under all *NIX O/S'es.

      $SIG{CHLD} = sub {while (waitpid(-1, WNOHANG) > 0){} };
      This is another way that works on some OS's.

      $SIG{CHLD} = 'IGNORE' # This often works with a few exceptions. # set 'IGNORE' is fastest if it does work. # But there is something to be said for work +ing # all the time, albeit slower (see first sol +ution)
      for those who are interested, the $SIG{CHLD} happens at the sigaction() level. And is faster because no subroutine will be called if the OS supports this option. I am just saying that it is not universally supported.
Re: Killing a child process, kills parent process
by Marshall (Canon) on Oct 13, 2011 at 15:13 UTC
    I am forking a child process from the main process. Then again forking another process from the child process

    Don't do that! Children should not make grand-children.

      Thanks Marshall. Could you guide me to any documentation/comments over this, like why we should not go for grandchildren.

      Is it a limitation from perl.
        There is another thread going on Socket descriptor passed across fork -- hanging where I posted a forked based client/server pair. Not exactly what the OP was 100% seeking, but enough to get started solving his issues. the basic "forumla" for how to implement the server/client pair is there.

        Perl is implemented in C and can pretty much do anything that C can do. In most cases, Perl can do what is needed. In many of the other cases, a C program can be written and interfaced to Perl, perhaps you have heard of XS modules?

        There are a number of "well known" models for client/server pairs. The most common is the fork based model because it is the most simple.

        Perl is not limited in anyway in terms of grandchildren. You can do it if you want, but I highly advise against it. I guess my first reason would be that there is no need. Second, it is complicated even if there was a need!

        A fork based server listens for new client connection requests. A new client shows up and "knocks on the Server's door" to get serviced, the parent delegates the handling of talking to this new person to a subordinate, a child. When the child gets finished, it just "dies", exits(). The parent who started the child gets notified by the Operating System. The resources allocated to that child get reclaimed for re-use.

        So parents can have lots of children - hundreds maybe. But when these children finish their jobs, the parent knows about and the resources (memory, socket descriptors, or what ever get freed and re-cycled).

        If a child is out there making its own children, then we don't have this simple model (this is a child acting like a parent). If one child makes 3 children from one child from the original parent made, what is anything is the original parent going to know? There can be complicated inefficiencies in returning resources to the main server pool and there is no need for it.

        Well anyway that is one reason. Read thru the code that I posted at the top of this reply. And if you like, we'll talk about it some more.

        Network programming is complicated stuff:
        I recommend the classic, Unix Network Programming by J.Richard Stevens. Unfortunately this pillar of computer science was taken from us at an early age. But his work has been updated with a more recent addition - I figure there are some, relatively minor mistakes in the new version.

        If I see a good Perl tut covering the basics, I will report back.