Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

hi all,
is it a known problem that alarm() function doesn't work as expected? The following code (see 'perl cookbook' or 'perldoc -f alarm') doesn't terminate after 5 seconds - it waits till ping timeouts (db01 is a known down host):

my $timeout = 5; eval { local $SIG{ALRM} = sub { die "alarm\n" }; # NB: \n required alarm $timeout; my $ret = qx/ping db01/; alarm 0; }; if ($@) { # timed out print "timeout handling ($! - $@) ...\n"; die unless $@ eq "alarm\n"; # propagate unexpected errors } else { # didn't print "no timeout timeout handling...\n"; }

I am writing watchdog scripts an I need response from the clients whithin a defined timeout period.

Any suggestions?

TIA

Retitled by g0n from 'timout problem with alarm'.

Replies are listed 'Best First'.
Re: timeout problem with alarm
by Limbic~Region (Chancellor) on Jul 12, 2005 at 14:02 UTC
    Anonymous Monk,
    Your problem isn't likely what you think it is. In version 5.8.0, Perl added "safe signals". Even though the signal is getting delivered, it is not acting on it immediately. In even more recent versions of Perl (>= 5.8.1), you can return to the old behavior by modifying a environment variable (PERL_SIGNALS=unsafe). See perlipc and perlrun for more information.

    Cheers - L~R

      Hi L~R,
      thank's for the very quick and helpful response. According to perlipc I shall (probably) use:
      Instead of setting $SIG{ALRM} : local $SIG{ALRM} = sub { die "alarm" }; try something like the following: use POSIX qw(SIGALRM); POSIX::sigaction(SIGALRM, POSIX::SigAction->new(sub { die "alarm" })) or die "Error setting SIGALRM handler: $!\n";
        Hi,
        this solution works only partly. It produces the expected alarm but the child process is still running 'til the network timeouts.
        So I will probably try 'fork/kill -9' to get rid of the child process...
        Is this a good idea?

        BTW (example; 1 of approx. 40 hosts):

        > uname -a SunOS db02 5.6 Generic_105181-17 sun4u sparc SUNW,Ultra-Enterprise > perl -v This is perl, v5.8.0 built for sun4-solaris
Re: timeout problem with alarm
by BrowserUk (Patriarch) on Jul 12, 2005 at 14:07 UTC

    If your using Win32, alarm doesn't work. Even more unfortuanate is that it fails silently, instead of with an error that might tell you something useful.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
    "Science is about questioning the status quo. Questioning authority".
    The "good enough" maybe good enough for the now, and perfection maybe unobtainable, but that should not preclude us from striving for perfection, when time, circumstance or desire allow.
Re: timeout problem with alarm
by derby (Abbot) on Jul 12, 2005 at 14:40 UTC

    What platform and perl? It works okay for me (Linux x86 2.4.20 and perl 5.8.2). It does leave a zombie process (check out the docs for that warning) that eventually cleans up when the ping times out. You might be better served with Net::Ping rather than the system ping.

    -derby