🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: pl.comp.lang.perl
1 messages
1 total messages Started by Adam Piatyszek Tue, 01 Mar 2011 14:26
Obsługa sygnałów a IPC::Open3
#52178
Author: 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
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads