in reply to Re^4: How to timeout if a call to an external program takes too long
in thread How to timeout if a call to an external program takes too long

Okay, but are you sure your tests actually show that the backticks were interrupted?

What do you mean by "interrupted"? Certainly I received and processed the alarms before the backticks finished executing. I don't know whether the processes that the backticks started were killed, but that wasn't the problem I was trying to solve anyway.

my $start = time; sub exec_time { return time - $start } alarm 5; $SIG{ALRM} = sub { printf "alarm (%d)!\n", exec_time() }; my $yawn = `sleep 10 ; echo "yawn"`; printf "(%d) yawn? $yawn\n", exec_time(); __END__ alarm (5)! (10) yawn? yawn

See? And here's the other one:

my $start = time; sub exec_time { return time - $start } my $yawn; eval { local $SIG{ALRM} = sub { die "alarm\n" }; alarm 5; $yawn = `sleep 3600 ; echo "yawn"`; alarm 0; }; printf "Time: %d\n", exec_time(); print $@ ? 'Timed out.' : 'Finished.'; print "\n"; print "yawn? $yawn\n"; __END__ Time: 5 Timed out. yawn?

Update: And the sleep from that second one is still running, even though the test script has finished. Obviously the job the backticks start still finishes on its own time. I'm guessing that when it hits echo, it will get a SIGPIPE.

Replies are listed 'Best First'.
Re^6: How to timeout if a call to an external program takes too long
by BrowserUk (Patriarch) on Aug 30, 2007 at 04:52 UTC

    Now I'm confused. In the second example, control was returned to the script after the 5 seconds. The external process continues, but as you say, that's a different problem,

    But in the first example, whilst the signal handler was invoked after 5 seconds, the command completed ('yawn' was returned) and that did not happen until the external 10 second sleep completed?

    Ie. Unless I am interpreting the output you posted incorrectly, the first example shows that the script cannot continue until the external command completes, even though the signal handler was invoked earlier than that.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

      In both cases, the the signal takes control away from the backticks and hands it to the signal handler.

      In the first example, the signal handler just prints a message and returns control to the backticks. That's why you get the message at five seconds. Since control returns to where it came from, the backticks finish (ten seconds after they started), and everything goes along as if there had been no alarm.

      In the second example, the signal handler uses die rather than just return. This way, it avoids returning control to the backticks. As such, $yawn is never set (it retains the value it had before the attempted assignment), and control flows out after the eval which caught the exception the signal handler threw.

        So, as examples of "How to timeout a call to an external program" go, the first one is completely useless as it does nothing except print a message via a 'longcall'.

        And the second one, whilst returning control to the calling program, leaves the spawned program running (or hung) with no possible mechanism to terminate it.


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.