[转帖]父进程与子进程communicate..利用IPC::Shareable的例子
作者:apile
Hi...這是昨天那個例子改用share memory的方式,兩相比較..我覺得
PIPE比較好點...尤其是有大量資料需要互傳的時候...
-------------------------------------------------------------------------------
本程序主要使用IPC::Shareable module来建立一块共同的share memory
以为所有程序所用,主要利用tie将%STATUS、%status与IPC::Shareable
tie在一起,其中SHM_GLUE用来向OS做注册一块memory的識別符號,因
此若程序失败, 未能正常清除share memory,必须利用OS提供的share
memory工具清除, 否则程序将无法启动。linux可以使用ipcrm清除
Parent Process利用sleep(),不做任何动作,而child Process的状态,
透过kill -ALARM getppid() 通知Parent,child Process的status已经
改变了..- #!/usr/bin/perl -w
- # p_shm.pl
- #---- 加载 module包含IPC::Shareable
- use strict;
- use POSIX qw(WNOHANG);
- use IPC::Shareable;
- #---- 定义常数
- use constant PREFORK_CHILDREN => 3;
- #--- 定义识别文字
- use constant SHM_GLUE => 'PERF';
- #--- 查测过程
- use constant DEBUG => 1;
- #--- 宣告全域变量
- my $DONE = 0; # set flag to true when server done
- #--- 纪录CHILD的STATUS
- my %STATUS = ();
- my %CHILDREN=();
- #--- 抓取Signal INT,TERM,ALRM----
- $SIG{INT} = $SIG{TERM}= sub{ $DONE++ };
- $SIG{ALRM} = sub {}; # receive alarm clock signals, but do nothing
- #----抓取 signal : CHLD
- $SIG{CHLD} = sub {
- while((my $child=waitpid(-1,WNOHANG)) > 0){
- delete $CHILDREN{$child};
- }
- };
- # create a shared memory segment for child status
- tie(%STATUS,'IPC::Shareable',SHM_GLUE,
- { create =>1,exclusive=>1,destroy=>1,mode=>0600})
- or die "Can't tie \%STATUS to shared memory: $!";
- # prefork some children
- make_new_child() for(1..PREFORK_CHILDREN); # prefork children
- #-- Main loop
- while(!$DONE){
- sleep; # sleep until a signal arrives(alarm clock or child)
- # get the list of idle children
- warn join(' ',map{"$_=>$STATUS{$_}"} keys %STATUS),"\n" if DEBUG;
- unless(%CHILDREN){ last; }
- }
- warn "Termination received, killing children\n" if DEBUG;
- #-------------杀掉所有Child Process
- kill TERM => keys %CHILDREN;
- sleep while %CHILDREN;
- warn "Normal termination.\n";
- exit 0;
- #---- 给launch_child cleanup child code
- sub make_new_child{
- die "can't fork :$!" unless(defined( my $child = fork()));
- if($child){ # child>0, so we're the parent
- warn "launching child $child\n" if DEBUG;
- $CHILDREN{$child} = 1;
- }else{
- do_child(); # child handles incoming connections
- exit 0; # child is done
- }
- }
- #--- 执行accept() loop fro each child ---
- sub do_child{
- my %status;
- #--将%status与IPC::Shareable tie在一起
- tie(%status,'IPC::Shareable', SHM_GLUE)
- or die "Child $$: can't tiel \%status to shared memory: $!";
- #----告知Parent Process,child process 状态已经改变
- $status{$$} ='idle'; kill ALRM=>getppid();
- for(1..1000000){ }
- #----告知Parent Process,child process 状态已经改变
- $status{$$} ='busy'; kill ALRM=>getppid();
- #----告知Parent Process,child process 状态已经改变
- for(1..1000000){ }
- $status{$$} = 'done'; kill ALRM=>getppid();
- warn "child $$: done\n" if DEBUG;
- }
- #---- delete the child's PID from %STATUS.
- sub cleanup_child{
- my $child=shift;
- delete $STATUS{$child};
- }
复制代码 |