in reply to Print inside SIGNALS

This code does not work..

alarm 2; $SIG{ALRM} = \&Finish; while (1==1){}; sub Finish { print "Timeout reached"; }

BUT... This code works... and after 2 seconds, the program dies...

alarm 2; $SIG{ALRM} = \&Finish; while (1==1){}; sub Finish { die; }

So something happens with print...

Replies are listed 'Best First'.
Re^2: Print inside SIGNALS
by haukex (Archbishop) on Jul 16, 2018 at 20:18 UTC

    I can replicate that the first snippet doesn't seem to output anything. However, it seems that the signal does get triggered, it just has something to do with buffering, as the following two examples work. Are you really just doing print "Timeout reached"; in your original code, without the newline or anything else that would cause the output to get flushed? See also Suffering from Buffering.

    $ perl -wMstrict -e 'alarm 2; $SIG{ALRM}=sub{ print "Timeout reached" }; while(){}' ^C $ perl -wMstrict -e 'alarm 2; $SIG{ALRM}=sub{ print "Timeout reached\n" }; while(){}' Timeout reached $ perl -wMstrict -e '$|++; alarm 2; $SIG{ALRM}=sub{ print "Timeout reached" }; while(){}' Timeout reached

    Elsewhere in this thread you said:

    My actual perl program is huge to post it here. It does not use threads but it execute many external commands.

    Well, the trick is to reduce the actual code down to an SSCCE. Delete some code from your program, if the problem persists, that code can stay deleted, but if the problem goes away, then put that code back in. Repeat this over and over until your code is a 10 to 20 line program that demonstrates the issue. Not only will this help you in narrowing down the problem, it'll give us a way to reproduce the actual issue ourselves.

    Other than the above buffering issue, I wouldn't exclude the possibility that one of the external programs is the culprit, or something else you're doing in your "huge" program. For example, perhaps something questionable is happening to STDOUT.

      I can replicate that the first snippet doesn't seem to output anything.

      Since you killed the process instead of letting it exit cleanly (e.g. using die or exit), it didn't get to flush its buffers.

        I can replicate that the first snippet doesn't seem to output anything.
        Since you killed the process instead of letting it exit cleanly (e.g. using die or exit), it didn't get to flush its buffers.

        Yes, hence my wording, which I've highlighted above. Or am I missing your point?

      Fool me... EUREKA! Buffering issue as suggested by haukex !!!!

      Thank you everybody....

Re^2: Print inside SIGNALS
by haj (Vicar) on Jul 16, 2018 at 20:34 UTC
    This is not so special. If you print to a terminal, you might note that this code does work, in the sense that the output appears after two seconds:
    alarm 2; $SIG{ALRM} = \&Finish; while (1==1){}; sub Finish { print "Timeout reached\n"; }
    After that, the endless loop continues. The only difference is the line feed: STDOUT is typically line buffered if output is to the terminal. So, you just don't see the output. For output to a file or socket, you might want to set $| to a true value.