🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: pl.comp.lang.perl
Article #52178

Obsługa sygnałów a IPC::Open3

#52178
From: Adam Piatyszek
Date: Tue, 01 Mar 2011 14:26
73 lines
3159 bytes
Witam,

Mam problem z obsługą sygnałów w skrypcie, którego zadaniem jest
monitorowanie czasu trwania i chwilowej szczytowej zajętości pamięci
podprocesu wykonywanego za pomocą open3. Skrypt ma działać podobnie jak
komenda systemowa 'time'.

Podproces jest wywoływany następująco:
my $pid;
eval { $pid = open3( $infh, $outfh, $errfh, $options->{cmd} ); };
die $@ if $@;

W dalszej części skryptu z użyciem IO::Select obsługuję uchwyty $outfh i
$errfh aby przechwycić standardowe wyjście z podprocesu i przesłać je na
zewnątrz. W między czasie dokonuję pomiaru czasu wykonania i pamięci za
pomocą wywołania funkcji:

sub get_mem_usage {
    my ( $pid, $max_mem_usage ) = @_;
    my %ppid_map;
    my $mem_usage = 0;
    if ( my $ps_pid = open my $psp, 'ps -d -o pid= -o ppid= -o vsz= |' ) {
        while (<$psp>) {
            chomp;
            my ( $tmp_pid, $ppid, $vsz ) = split;
            # Skip 'ps' process used for measurements
            next if $tmp_pid == $ps_pid;
            $ppid_map{$ppid}{PID} = $tmp_pid;
            $ppid_map{$ppid}{VSZ} += $vsz;
            $mem_usage = $vsz if $tmp_pid == $pid;
        }
        close $psp;
        while ( $ppid_map{$pid}{PID} ) {
            $mem_usage += $ppid_map{$pid}{VSZ};
            $pid = $ppid_map{$pid}{PID};
        }
        if ( $mem_usage > ${$max_mem_usage} ) {
            ${$max_mem_usage} = $mem_usage;
        }
    }
}

Zakończenie skryptu następuje, gdy podproces nie ma nic więcej do roboty
i kończy działanie:

waitpid $pid, 0;
my $child_exit_code = $? >> 8;


Chciałbym przechwycić wszystkie sygnały przychodzące z zewnątrz i
przesłać je dalej do podprocesu tak aby proces ps-a uruchamiany w
get_mem_usage() nie reagował na nie. Próbowałem coś takiego:

my $pid;
[...]
eval { $pid = open3( $infh, $outfh, $errfh, $options->{cmd} ); };
die $@ if $@;

sub sig_handler {
    my ($sig_name) = @_;
    warn "Intercepting $sig_name $pid\n";
    kill $sig_name, $pid;
}
foreach my $sig (qw/ABRT ALRM CONT HUP INT QUIT STOP TERM TSTP USR1 USR2/) {
    $SIG{$sig} = \&sig_handler;
}

Jednakże nie działa to jak powinno. Nadal proces ps-a przechwytuje
sygnały. Ma ktoś może pomysł jak to poprawić?

Dzięki z góry za pomoc!
Pozdrawiam,
/Adam
Technical Details
Message-ID: <ikjl04$2grt$1@opal.icpnet.pl>
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.rmf.pl!nf1.ipartners.pl!ipartners.pl!newsfeed.icp.pl!newsb.icpnet.pl!not-for-mail

Show Full Headers
Complete Article Headers
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.rmf.pl!nf1.ipartners.pl!ipartners.pl!newsfeed.icp.pl!newsb.icpnet.pl!not-for-mail
From: Adam Piatyszek <ediap@users.sourceforge.net>
Newsgroups: pl.comp.lang.perl
Subject: Obsługa sygnałów a IPC::Open3
Date: Tue, 01 Mar 2011 15:26:13 +0100
Organization: ICP News Server
Lines: 73
Message-ID: <ikjl04$2grt$1@opal.icpnet.pl>
NNTP-Posting-Host: c184-240.icpnet.pl
Mime-Version: 1.0
X-Trace: opal.icpnet.pl 1299011397 82813 85.221.184.240 (1 Mar 2011 20:29:57 GMT)
X-Complaints-To: abuse@icpnet.pl
NNTP-Posting-Date: Tue, 1 Mar 2011 20:29:57 +0000 (UTC)
User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.13) Gecko/20101214 Lightning/1.0b2 Thunderbird/3.1.7
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit