FAQ
Hi group,

I try to catch a signal, write out some statistics about my running
perl program and continue afterwards with the program.

use strict;
no utf8;
use MyProgram::Lib;
use Encode;
use Socket;
use File::Path;
use File::Find;
use Getopt::Std;
die("MyProgram::Lib->new failed\n") if ( !(my $init = MyProgram::Lib->init) );
$SIG{ILL} = \&write_status;
:
sub write_status
{
my $sigName = shift;

print( STDERR "Signal ILL catched" );
return;
}
Within bash I send the signal with "kill -4 <procID>"
Unfortunately my program die after catching the signal.
Without the print it dies too.
Also within debugger (perl -d:ptkdb) it dies after the return statement.

Is it possible to interrupt a perl program and continue afterwards?

Thanks
Matthias
--
Don't Panic

Search Discussions

  • Shawn H Corey at Feb 15, 2010 at 8:36 pm

    Matthias Meyer wrote:
    Hi group,

    I try to catch a signal, write out some statistics about my running
    perl program and continue afterwards with the program.

    use strict;
    no utf8;
    use MyProgram::Lib;
    use Encode;
    use Socket;
    use File::Path;
    use File::Find;
    use Getopt::Std;
    die("MyProgram::Lib->new failed\n") if ( !(my $init = MyProgram::Lib->init) );
    $SIG{ILL} = \&write_status;
    :
    sub write_status
    {
    my $sigName = shift;

    print( STDERR "Signal ILL catched" );
    return;
    }
    Within bash I send the signal with "kill -4 <procID>"
    Unfortunately my program die after catching the signal.
    Without the print it dies too.
    Also within debugger (perl -d:ptkdb) it dies after the return statement.

    Is it possible to interrupt a perl program and continue afterwards?

    Thanks
    Matthias
    What OS?

    Normally a program continues but if it is waiting or sleeping, it
    continues after the command. You have to redo the command until it
    terminates correctly. Example: waiting for a child process:

    my $child_pid = 0;
    WAIT_BLOCK: {
    $child_pid = wait();
    redo WAIT_BLOCK if $child_pid == 0 || $child_pid < -1;
    }

    --
    Just my 0.00000002 million dollars worth,
    Shawn

    Programming is as much about organization and communication
    as it is about coding.

    I like Perl; it's the only language where you can bless your
    thingy.
  • C.DeRykus at Feb 16, 2010 at 2:05 am

    On Feb 15, 12:35 pm, shawnhco...@gmail.com (Shawn H Corey) wrote:
    Matthias Meyer wrote:
    Hi group,
    I try to catch a signal, write out some statistics about my running
    perl program and continue afterwards with the program.
    use strict;
    no  utf8;
    use MyProgram::Lib;
    use Encode;
    use Socket;
    use File::Path;
    use File::Find;
    use Getopt::Std;
    die("MyProgram::Lib->new failed\n") if ( !(my $init = MyProgram::Lib->init) );
    $SIG{ILL} = \&write_status;
    :
    sub write_status
    {
    my $sigName = shift;
    print( STDERR "Signal ILL catched" );
    return;
    }
    Within bash I send the signal with "kill -4 <procID>"
    Unfortunately my program die after catching the signal.
    Without the print it dies too.
    Also within debugger (perl -d:ptkdb) it dies after the return statement.
    Is it possible to interrupt a perl program and continue afterwards?
    Thanks
    Matthias
    What OS?

    Normally a program continues but if it is waiting or sleeping, it
    continues after the command.  You have to redo the command until it
    terminates correctly.  Example:  waiting for a child process:

    my $child_pid = 0;
    WAIT_BLOCK: {
    $child_pid = wait();
    redo WAIT_BLOCK if $child_pid == 0 || $child_pid < -1;

    }
    No, you don't need 'redo' on a blocking wait. I see why you
    might conclude that reading the waitpid doc but I believe the
    that doc is mis-leading in not clarifying that only a non-blocking
    wait, ie, WNOHANG, will potentially return a 0.

    See:
    http://groups.google.de/group/perl.beginners/browse_thread/thread/71ac675f384a9828

    Here're the key parts of that exchange which may look remarkably
    familiar :)
    On some systems, a value of 0 indicates that there are processes still
    running.
    I see that but I suspect Perl's waitpid doc is unintentionally
    misleading.
    A quick look at Linux and OpenBSD wait(2) manpages specifies a 0
    return can occur only with FLAGS set to WNOHANG.
    OpenBSD: from waitpid(2) manpage:
    Otherwise, if WNOHANG is specified and there
    are no stopped or exited children, 0 is returned.
    Linux:
    ... if WNOHANG was specified and no child(ren) specified by
    pid
    has yet changed state, then 0 is returned.
    In other words, waitpid can return a value which is not the pid of the
    child you requested. Therefore redo, since it's a foreach loop. This,
    of course, is only true on some systems; it may not be true on yours.
    If there's a system where a blocking waitpid could return
    something
    other than -1 or the specific pid you waited on, that'd be true.
    But,
    even then, you'd have to be careful that a -1 indicating a reaped
    process didn't cause an endless loop due to the 'redo'.
    --
    Charles DeRykus
  • Shawn H Corey at Feb 16, 2010 at 1:40 pm

    C.DeRykus wrote:
    On Feb 15, 12:35 pm, shawnhco...@gmail.com (Shawn H Corey) wrote:
    Normally a program continues but if it is waiting or sleeping, it
    continues after the command. You have to redo the command until it
    terminates correctly. Example: waiting for a child process:

    my $child_pid = 0;
    WAIT_BLOCK: {
    $child_pid = wait();
    redo WAIT_BLOCK if $child_pid == 0 || $child_pid < -1;

    }
    No, you don't need 'redo' on a blocking wait. I see why you
    might conclude that reading the waitpid doc but I believe the
    that doc is mis-leading in not clarifying that only a non-blocking
    wait, ie, WNOHANG, will potentially return a 0.
    From the man page on wait: Otherwise they block until either a child
    changes state or a signal handler interrupts the call.

    The system call wait(2) does return when interrupted by a signal. What
    is not clear in the Perl documentation is whether it puts a wrapper
    around the wait(2) to filter out when it returns from a signal.

    So, be paranoid: put the wait in a block and redo it until its response
    is not -1 or positive.

    Note that this is also true of sleep; it may return early if interrupted
    by a signal.


    --
    Just my 0.00000002 million dollars worth,
    Shawn

    Programming is as much about organization and communication
    as it is about coding.

    I like Perl; it's the only language where you can bless your
    thingy.
  • C.DeRykus at Feb 16, 2010 at 4:21 pm

    On Feb 16, 5:40 am, shawnhco...@gmail.com (Shawn H Corey) wrote:
    C.DeRykus wrote:
    On Feb 15, 12:35 pm, shawnhco...@gmail.com (Shawn H Corey) wrote:
    Normally a program continues but if it is waiting or sleeping, it
    continues after the command.  You have to redo the command until it
    terminates correctly.  Example:  waiting for a child process:
    my $child_pid = 0;
    WAIT_BLOCK: {
    $child_pid = wait();
    redo WAIT_BLOCK if $child_pid == 0 || $child_pid < -1;
    }
    No, you don't need 'redo'  on a blocking wait.  I see why you
    might conclude that  reading the waitpid doc but I believe the
    that doc is mis-leading in not clarifying that only a non-blocking
    wait, ie, WNOHANG, will potentially return a 0.
    From the man page on wait:  Otherwise they block until either a child
    changes state or a signal handler interrupts the call.

    The system call wait(2) does return when interrupted by a signal.  What
    is not clear in the Perl documentation is whether it puts a wrapper
    around the wait(2) to filter out when it returns from a signal.

    So, be paranoid:  put the wait in a block and redo it until its response
    is not -1 or positive.
    No, you don't need to do that. If the child is interrupted by an
    uncaught
    signal, the child terminates and its status can be inspected, eg.

    use POSIX ":sys_wait_h";

    my $reaped_pid = wait();
    if ( WIFSIGNALED($?) ) { # uncaught signal
    print "child terminated by a ", WTERMSIG($?), "\n";
    }

    ( See perlipc. Also, 5.10 introduced something called
    ${^CHILD_ERROR_NATIVE} mentioned in the wait
    doc whose significance I don't understand completely.)

    Note that this is also true of sleep; it may return early if interrupted
    by a signal.
    ?
    sleep is implemented with a SIGALRM and, if there're dueling SIGALRM
    signals, you can get an early return, but that's a different issue.

    --
    Charles DeRykus
  • Shawn H Corey at Feb 17, 2010 at 1:08 pm

    C.DeRykus wrote:
    No, you don't need to do that. If the child is interrupted by an
    uncaught
    signal
    I'm not talking about the child being interrupted; I'm talking about the
    parent.

    As I said, the Perl documentation is not clear if it's wait command
    filters out signals not about its children.

    Come to think of it, it shouldn't. If it did, there's no way to
    interrupt a wait on those rare times you want to.

    And it happens with sleep too. sleep can be interrupted by a signal
    that's not an alarm.


    --
    Just my 0.00000002 million dollars worth,
    Shawn

    Programming is as much about organization and communication
    as it is about coding.

    I like Perl; it's the only language where you can bless your
    thingy.
  • C.DeRykus at Feb 17, 2010 at 4:30 pm

    On Feb 17, 5:08 am, shawnhco...@gmail.com (Shawn H Corey) wrote:
    C.DeRykus wrote:
    No, you don't need to do that.  If the child is interrupted by an
    uncaught
    signal
    I'm not talking about the child being interrupted; I'm talking about the
    parent.

    As I said, the Perl documentation is not clear if it's wait command
    filters out signals not about its children.
    Again no. Potentially they could, but they're not.
    A newer Unix always interrupts a wait or waitpid.
    Come to think of it, it shouldn't.  If it did, there's no way to
    interrupt a wait on those rare times you want to.
    Right. Typically, to timeout a child that might take too long,
    you use an eval {} and alarm().
    And it happens with sleep too.  sleep can be interrupted by a signal
    that's not an alarm.
    Yes. Any "slow" or blocking system call will by default be
    interruptible. (Old Unixes used to return an error when
    "slow" or blocking calls were interrupted and set errno
    to EINTR too which made programming much messier).

    --
    Charles DeRykus
  • C.DeRykus at Feb 16, 2010 at 1:26 am

    On Feb 15, 11:59 am, matthias.me...@gmx.li (Matthias Meyer) wrote:
    Hi group,

    I try to catch a signal, write out some statistics about my running
    perl program and continue afterwards with the program.

    use strict;
    no  utf8;
    use MyProgram::Lib;
    use Encode;
    use Socket;
    use File::Path;
    use File::Find;
    use Getopt::Std;
    die("MyProgram::Lib->new failed\n") if ( !(my $init = MyProgram::Lib->init) );
    $SIG{ILL} = \&write_status;
    :
    sub write_status
    {
    my $sigName = shift;

    print( STDERR "Signal ILL catched" );
    return;}

    Within bash I send the signal with "kill -4 <procID>"
    Unfortunately my program die after catching the signal.
    Without the print it dies too.
    Also within debugger (perl -d:ptkdb) it dies after the return statement.

    Is it possible to interrupt a perl program and continue afterwards?
    Most signals can be caught and programs can continue. However SIGILL
    by default causes program termination and can't be ignored. Core
    dumps
    are often generated.

    Any END {} blocks still execute though.

    --
    Charles DeRykus
  • Matthias Meyer at Feb 17, 2010 at 9:42 pm

    C.DeRykus wrote:
    On Feb 15, 11:59 am, matthias.me...@gmx.li (Matthias Meyer) wrote:
    Hi group,

    I try to catch a signal, write out some statistics about my running
    perl program and continue afterwards with the program.

    use strict;
    no  utf8;
    use MyProgram::Lib;
    use Encode;
    use Socket;
    use File::Path;
    use File::Find;
    use Getopt::Std;
    die("MyProgram::Lib->new failed\n") if ( !(my $init =
    MyProgram::Lib->init) ); $SIG{ILL} = \&write_status;
    :
    sub write_status
    {
    my $sigName = shift;

    print( STDERR "Signal ILL catched" );
    return;}

    Within bash I send the signal with "kill -4 <procID>"
    Unfortunately my program die after catching the signal.
    Without the print it dies too.
    Also within debugger (perl -d:ptkdb) it dies after the return statement.

    Is it possible to interrupt a perl program and continue afterwards?
    Most signals can be caught and programs can continue. However SIGILL
    by default causes program termination and can't be ignored. Core
    dumps
    are often generated.

    Any END {} blocks still execute though.

    --
    Charles DeRykus
    SIGIO work.
    Thanks
    Matthias
    --
    Don't Panic

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupbeginners @
categoriesperl
postedFeb 15, '10 at 8:05p
activeFeb 17, '10 at 9:42p
posts9
users3
websiteperl.org

People

Translate

site design / logo © 2021 Grokbase