hengha has asked for the wisdom of the Perl Monks concerning the following question:
in my pre-forking Daemon, I have parent process which monitoring the status of the forked child and fork new one whenever existing child is dead. there are also a IPC shareable var which holds epoch time value is shared between parent and child process.
I have 3 sample scripts.
1. preload.pl: init a ipc shareable variable $newvalue.
2. ipcprocesses.pm: ipcprocess perl module which is used by ipcprocess perl script.
3. ipcprocesses.pl: main script.
what I expect is that whenever a child is dead, parent will be notified and re-fork a new one which INHERITS the shareble variable from the parent. since the shareable variable will be updated quite often, so the new forked child should also inherits the most current value.
The problem I got is that: new forked child do not get the lastest value from shareable variable but only the inited value when parent start up.
by my investigation,it turned out whenever a child dead, parent did get notified by SIG ALARM from child and got the value from shared var, however ,new forked child did not get the value from it.
I pasted the 3 scripts below (sorry, a little bit long), please take a look for me and drop something if you have. thank you.
#!/usr/bin/perl -w #preload.pl use IPC::Shareable; my $newvalue; tie $newvalue,'IPC::Shareable','kali',{create => 1,size => 65536}; $newvalue=0;
#!/usr/bin/perl -w #ipcprocesses.pm. #you may find some of the variables are not defined here #that is fine for demo purpose. package ipcprocesses; use POSIX; use IPC::Shareable; my $newvalue; my $num_children = 0; sub new { my $class = shift; my $this = { 'field' => 1 }; bless ($this,$class); tie $newvalue,'IPC::Shareable','kali'; return ($this); } $SIG{CHLD} = \&DO_AirGREAPER; $SIG{INT} = $SIG{TERM} = \&DO_AirGStopHandler; $SIG{ALRM} = sub {}; sub DO_AirGStopHandler { local( $SIG{CHLD} ) = 'IGNORE'; kill 'INT' => keys %H_children; exit; } sub DO_AirGREAPER { # takes care of dead children my ( $N_pid ); # If a second child dies while in the signal handler #caused by the # first death, we won't get another signal. So must # loop here else # we will leave the unreaped child as a zombie. And the # next time # two children die we get another zombie. And so on. while ( ($N_pid = waitpid(-1, &WNOHANG)) > 0 ) { if (WIFEXITED $?){ $num_children--; } } $SIG{CHLD} = \&DO_AirGREAPER; } sub DO_Initprocesspool { my $this = shift; # Fork off our children. for ( 1 .. 2 ) { $this->DO_newchild(); } } sub DO_newchild { my $this = shift; if ($pid = fork) { #parent $this->{'field'} = $newvalue; $num_children++; print 'parent'.$$.'|'.$this->{'field'}."\n"; return; } else{ my $newvalue; tie $newvalue,"IPC::Shareable",'kali'; #Children can not return from this subroutine $SIG{INT} = 'DEFAULT'; #make SIGINT kill us as it did befo +re while(1) { sleep 2; print 'child'.$$.'|'.$this->{'field'}."\n"; $newvalue = time(); } } exit; } sub DO_MaintainPopulation { my $this = shift; for ( my $i = $num_children; $i < 2; $i++ ) { # top up the child pool $this->DO_newchild(); } } 1;
#!/usr/bin/perl -w #ipcprocesses.pl use strict; use lib qw (/somepath); use ipcprocesses; my $fork = ipcprocesses->new(); while ( 1 ) { $fork->DO_MaintainPopulation(); }
Edited by planetscape - added readmore tags and rudimentary formatting
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: IPC and communication between Parent and Child Process
by shmem (Chancellor) on Oct 25, 2006 at 07:42 UTC | |
by hengha (Initiate) on Oct 26, 2006 at 06:42 UTC | |
by shmem (Chancellor) on Oct 26, 2006 at 11:10 UTC |