在Perl中的进程之间发送消息

前端之家收集整理的这篇文章主要介绍了在Perl中的进程之间发送消息前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在尝试使用信号实现进程之间的通信.首先,父进程启动子进程,它执行一些工作,然后等待来自子进程的消息,然后再次发信号通知子进程,以便子进程继续处理等等.

我不确定实现这个的正确方法是什么,但这是我的第一次尝试:

use warnings;
use strict;
use feature qw(say);

my $forever=1000000;
my $parPID=$$;
my $child = fork();
if( $child == 0 ){
  runSubProc($parPID,$forever);
}

$SIG{"USR1"}=sub { 
  say "Parent: got signal 1";
  $SIG{"USR1"}=sub {
    say "Parent: got signal 2";
    exit 0;
  };
  sleep 5;
  kill 'USR1',$child;
  sleep $forever;
};

say "Waiting for child processes..";
sleep $forever;


sub runSubProc {
  my ($parPID,$forever)=@_;

  $SIG{"USR1"}=sub { 
    say "Child: got signal 1"; 
    $SIG{"USR1"}=sub {
      say "Child: got signal 2"; 
      exit 0;
    };
    sleep 7;
    kill 'USR1',$parPID;
    sleep $forever;
  };
  sleep 5;
  kill 'USR1',$parPID;
  sleep $forever;
}

这不起作用,输出是:

Waiting for child processes..
Parent: got signal 1
Child: got signal 1

然后它挂起..

解决方法

根本原因是你在信号处理程序中永远睡眠$.因为你的进程已经在处理’SIGUSR1′,所以下一个终止​​信号不会被处理 – 这是为了避免信号中断信号的各种肮脏.避免在你的处理程序中阻止任何事情.

这似乎有效:

$SIG{'USR1'} = \&handle_USR1;

my $ppid      = $$;
my $child_pid = fork();

sub handle_USR1 {
    if ( $signalled++ ) { print "$$: got second USR1\n"; exit 0 }

    print "$$: caught SIGUSR1\n";
    if ( not $child_pid ) {
        print "$$: Child got a SIGUSR1\n";
        sleep 7;
        print "$$: (child) sending signal to $ppid\n";
        kill 'USR1',$ppid;
    } else {
        print "$$: (parent) got USR1\n";
        sleep 5;
        print "$$: parent signalling child\n";
        kill 'USR1',$child_pid;
    }
}

if ($child_pid) {
    print "$$( parent ) waiting\n";
    sleep 500;
} else {
    print "$$: (child) waiting\n";
    sleep 5;
    print "$$: Child signalling $ppid\n";
    kill 'USR1',$ppid;
    sleep 500;
}

您可能需要稍微重新洗牌,但核心要点是 – 动态重新定义您的信号处理程序,尤其是通过将睡眠置于其中来“拖延”它们将打破信号机制.

猜你在找的Perl相关文章