返回列表 回复 发帖

[转帖]父进程与子进程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已经
改变了..
  1. #!/usr/bin/perl -w
  2. # p_shm.pl
  3. #---- 加载 module包含IPC::Shareable
  4. use strict;
  5. use POSIX qw(WNOHANG);
  6. use IPC::Shareable;
  7. #---- 定义常数
  8. use constant PREFORK_CHILDREN => 3;
  9. #--- 定义识别文字
  10. use constant SHM_GLUE => 'PERF';
  11. #--- 查测过程
  12. use constant DEBUG => 1;
  13. #--- 宣告全域变量
  14. my $DONE = 0; # set flag to true when server done
  15. #--- 纪录CHILD的STATUS
  16. my %STATUS = ();
  17. my %CHILDREN=();
  18. #--- 抓取Signal INT,TERM,ALRM----
  19. $SIG{INT} = $SIG{TERM}= sub{ $DONE++ };
  20. $SIG{ALRM} = sub {}; # receive alarm clock signals, but do nothing
  21. #----抓取 signal : CHLD
  22. $SIG{CHLD} = sub {
  23. while((my $child=waitpid(-1,WNOHANG)) > 0){
  24. delete $CHILDREN{$child};
  25. }
  26. };
  27. # create a shared memory segment for child status
  28. tie(%STATUS,'IPC::Shareable',SHM_GLUE,
  29. { create =>1,exclusive=>1,destroy=>1,mode=>0600})
  30. or die "Can't tie \%STATUS to shared memory: $!";
  31. # prefork some children
  32. make_new_child() for(1..PREFORK_CHILDREN); # prefork children
  33. #-- Main loop
  34. while(!$DONE){
  35. sleep; # sleep until a signal arrives(alarm clock or child)
  36. # get the list of idle children
  37. warn join(' ',map{"$_=>$STATUS{$_}"} keys %STATUS),"\n" if DEBUG;
  38. unless(%CHILDREN){ last; }
  39. }
  40. warn "Termination received, killing children\n" if DEBUG;
  41. #-------------杀掉所有Child Process
  42. kill TERM => keys %CHILDREN;
  43. sleep while %CHILDREN;
  44. warn "Normal termination.\n";
  45. exit 0;
  46. #---- 给launch_child cleanup child code
  47. sub make_new_child{
  48. die "can't fork :$!" unless(defined( my $child = fork()));
  49. if($child){ # child>0, so we're the parent
  50. warn "launching child $child\n" if DEBUG;
  51. $CHILDREN{$child} = 1;
  52. }else{
  53. do_child(); # child handles incoming connections
  54. exit 0; # child is done
  55. }
  56. }
  57. #--- 执行accept() loop fro each child ---
  58. sub do_child{
  59. my %status;
  60. #--将%status与IPC::Shareable tie在一起
  61. tie(%status,'IPC::Shareable', SHM_GLUE)
  62. or die "Child $$: can't tiel \%status to shared memory: $!";
  63. #----告知Parent Process,child process 状态已经改变
  64. $status{$$} ='idle'; kill ALRM=>getppid();
  65. for(1..1000000){ }
  66. #----告知Parent Process,child process 状态已经改变
  67. $status{$$} ='busy'; kill ALRM=>getppid();
  68. #----告知Parent Process,child process 状态已经改变
  69. for(1..1000000){ }
  70. $status{$$} = 'done'; kill ALRM=>getppid();
  71. warn "child $$: done\n" if DEBUG;
  72. }
  73. #---- delete the child's PID from %STATUS.
  74. sub cleanup_child{
  75. my $child=shift;
  76. delete $STATUS{$child};
  77. }      
复制代码
哈哈哈!!!!你的IP是不是?我都知道了!!!
返回列表