- 论坛徽章:
- 0
|
看了你的关于:父进程与子进程communicate..利用PIPE的例子(perl原创精华文章!)
由于水平有限,逻辑思路我也没有理清楚!
能否详细说明一下,谢谢!
- #!/usr/bin/perl
- use strict;
- use IO::Select;
- use POSIX qw(WNOHANG);
- #---Define constants:定义准备先fork几个Process
- use constant PREFORK_CHILDREN =>; 3;
- # debugging information:显示过程
- use constant DEBUG =>; 1;
- # declare globals
- my $DONE=0; # set flag to true when server done
- my %STATUS = (); #child status information, child pid form keys of the ha
- sh, status form the values
- #--- 纪录所有Child Process的id...
- my %CHILDREN = ();
- #---Interrupt handles,跳出loop
- $SIG{TERM} = $SIG{INT}=$SIG{HUP} = sub { $DONE++ };
- #--- get CHLD Signal
- $SIG{CHLD} = sub {
- while((my $child=waitpid(-1,WNOHANG)) >; 0){
- delete $CHILDREN{$child};
- }
- };
- # create a pipe for IPC:建立PIPE
- pipe(CHILD_READ,CHILD_WRITE) or die "Can't make pipe!\n";
- my $IN = IO::Select->;new(\*CHILD_READ);
- # prefork some children
- make_new_child() for (1..PREFORK_CHILDREN);
- # main loop
- while(!$DONE){
- # avoid parent block in the I/O call
- if ($IN->;can_read){ # got a message from one of the children
- my $message;
- next unless sysread(CHILD_READ,$message,4096);
- # may contain several messages
- my @messages = split "\n",$message;
- # retrive every pid and status code
- foreach (@messages){
- next unless my ($pid,$status) = /^(\d+) (.+)$/;
- # change status
- if($status ne "done"){
- $STATUS{$pid} = $status;
- }else{
- # delete pid
- delete $STATUS{$pid};
- }
- }
- }
- warn join(' ',map {"$_=>;$STATUS{$_}"} keys %STATUS),"\n" if DEBUG;
- last unless %CHILDREN
- }
- warn "Termination received, killing children\n" if DEBUG;
- #-------------杀掉所有Child Process
- kill TERM =>; keys %CHILDREN;
- sleep while %CHILDREN;
- warn "Normal termination.\n";
- exit 0;
- #---- 建立新的Process
- sub make_new_child{
- die "can't fork :$!" unless(defined( my $child = fork()));
- if($child){ # child >; 0, so we're the parent
- $CHILDREN{$child} = 1;
- warn "launching child $child\n" if DEBUG;
- }else{
- close CHILD_READ; # no need to read from pipe
- do_child(); # child handles incoming connections
- exit 0; # child is done
- }
- }
- #------ child process
- sub do_child{
- # write status code: idle
- syswrite CHILD_WRITE,"$$ idle\n";
- for(1..1000000){ };
- syswrite CHILD_WRITE,"$$ busy\n";
- for(1..1000000){ };
- syswrite CHILD_WRITE,"$$ done\n";
- }
复制代码 |
|