http://qs1969.pair.com?node_id=293084

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

fellow monks

I would like to enforce a time-out for each element in an array as it is processed in a foreach loop. After a prescribed time limit, I would like to go to the next element in an array. To illustrate this, I have put together the following sample script.

#!/usr/bin/perl -w use strict; use POSIX qw/strftime/; strftime "%H:%M:%S", localtime; my @sleepvals = qw /1 2 3 4 5 6 7 8/; print strftime "%H:%M:%S", localtime; print "\n"; foreach my $sleepval (@sleepvals) { sleep($sleepval); print strftime "%H:%M:%S", localtime; print "\n"; }
The output to this would look something like this:
01:03:39 01:03:40 01:03:42 01:03:45 01:03:49 01:03:54 01:04:00 01:04:07 01:04:15
I would like to enforce a time-out where, if sleep() takes longer than 3 seconds, sleep() is terminated, the rest of the foreach loop is processed and the script proceeds to the next element in the array. As an arbitrary example, I would like to set each iteration to, say 3 seconds, so the output would look as follows:
01:03:39 01:03:40 01:03:42 01:03:45 01:03:48 01:03:51 01:04:54 01:04:57
Thanks in advance for any suggestions.

cheers, -dave

Replies are listed 'Best First'.
Re: enforce timeout in loop
by perlmonkey (Hermit) on Sep 22, 2003 at 05:28 UTC
    Follow the example in the perldoc page for alarm. Change your for loop to look like:
    foreach my $sleepval (@sleepvals) { eval { local $SIG{ALRM} = sub { die }; alarm 3; sleep($sleepval); }; print strftime "%H:%M:%S", localtime; print "\n"; }
      ++perlmonkey. beautiful. This is exactly what I was looking for.

      cheers, -dave

Re: enforce timeout in loop
by Zaxo (Archbishop) on Sep 22, 2003 at 05:24 UTC

    I think we need to know what kind of processing you're really doing on those array elements. Are you timing out a socket or some other IO handle or a child process? The timeout mechanism will differ for each. Socket flags, alarm, four-arg select, or kill/signal handling may be called for, but which depends on what you're doing.

    After Compline,
    Zaxo

Re: enforce timeout in loop
by rir (Vicar) on Sep 24, 2003 at 14:32 UTC
    It sounds as if you know your maximum sleep time upfront. If this is the case you can:
    # off hand code foreach my $sleepval ( @sleepvals) { sleep( $sleepval < $maxsleep ? $sleepval : $maxsleep); print strftime "%H:%M:%s", localtime; print "\n"; }