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

I'm writing a production system and need some advise.

I need to keep performance quick and reliable.

I'm catching alot of signals so perls sleep() gets inturrupted alot.

I need a reliable way of sleeping for a specifed interval.

example sleep loop logic :
1. Get the system time.
2. run a sleep loop for X seconds
3. IF it gets inturrupted, check the real number of seconds passed since it has been asleep(via another system time call)
4. if its enough, break out of the sleep loop, else go to #2.


anyone have a better idea?

System details:
running perl 5.8
OS is AIX 5.1 dev, AIX 5.3 prod
  • Comment on need a reliable way to "sleep" while using signals

Replies are listed 'Best First'.
•Re: need a reliable way to "sleep" while using signals
by merlyn (Sage) on Jan 11, 2005 at 17:41 UTC
    use POE. Set up a single session, assign your signals to states, put your code in the state code, and have one miscellaneous state that is the length of time you need, triggered by a timer. POE will manage the timer event to ensure it gets delivered at the proper time.

    -- Randal L. Schwartz, Perl hacker
    Be sure to read my standard disclaimer if this is a reply.

Re: need a reliable way to "sleep" while using signals
by Zaxo (Archbishop) on Jan 11, 2005 at 18:31 UTC

    Four-arg select returns -1 if it is interrupted, 0 if timed out. Using that and Time::HiRes, here's a demo,

    #!/usr/bin/perl # file: sigdemo use warnings; use strict; use Time::HiRes qw/gettimeofday tv_interval/; $SIG{INT} = sub {}; my $timer = shift; my $start = [gettimeofday]; { last if $timer <= 0; $timer -= tv_interval($start), redo if select undef, undef, undef, $timer; } print "*Yawn* what time is it?\n";
    (Untested, no AIX here). That is meant to sleep through Ctrl-C keyboard interrupts for X seconds given on the command line.

    After Compline,
    Zaxo

Re: need a reliable way to "sleep" while using signals
by BrowserUk (Patriarch) on Jan 11, 2005 at 18:53 UTC

    This seems to work okay on Win32.

    #! perl -slw use strict; $|++; sub sleepFor{ my @sigs = keys %SIG; local %SIG; $SIG{ $_ } = eval "sub{ print 'Got signal $_'; }" for @sigs; my $t = time() + $_[ 0 ]; sleep 1 while time() < $t } print scalar localtime; sleepFor $ARGV[ 0 ]; print scalar localtime; __END__ P:\test>421347 10 Tue Jan 11 18:51:06 2005 Got signal INT Got signal INT Got signal INT Got signal QUIT Got signal INT Got signal QUIT Got signal INT Tue Jan 11 18:51:16 2005

    Examine what is said, not who speaks.
    Silence betokens consent.
    Love the truth but pardon error.
Re: need a reliable way to "sleep" while using signals
by bluto (Curate) on Jan 11, 2005 at 19:12 UTC
    If you just want something low-tech this should work. I've used something similar in production on AIX 5.1 without a problem.

    Update: I know this works with signals. I can't say my code caught a lot of them though since I avoid them as much as possible.