in reply to Re^2: Cannot catch ALRM signal for timeout
in thread Cannot catch ALRM signal for timeout

ikegami, what do you mean by "move the eof into the eval"? I try this:
sub process_scheme{ my ($output_file) = @_; open (OUTPUT_FILE, ">", $output_file) || die "cannot open lo +g file"; my $scheme_pid = open (WORKER, "worker_program < $input |") || die "cannot pipe worker"; my $str; while (1) { eval{ local $SIG{ALRM} = sub { die "alarm\n" }; # NB: \n r +equired alarm 1; if (eof(WORKER)){ close WORKER; close OUTPUT; return 1; } $str = <WORKER>; alarm 0; # if this line is removed, the signal is ca +ught, but outside of eval, so it halts the script }; if ($@) { close OUTPUT_FILE; close WORKER; return 0; } # process the line # some code ... # print the line to log print OUTPUT_FILE $str; } }
but it still does not work :( Thank you for your hint, tho

Replies are listed 'Best First'.
Re^4: Cannot catch ALRM signal for timeout
by ikegami (Patriarch) on Dec 08, 2009 at 21:24 UTC

    but it still does not work

    What doesn't work?

    The timeout works fine. I changed

    my $scheme_pid = open (WORKER, "worker_program < $input |")
    to
    my $scheme_pid = open (WORKER, "-|", $^X, '-e', '$|=1; for (1..100) { +print "%d\n", $_*$t; sleep(2) }')

    and the timeout triggered. The log file contained only "0".

    You'll need to fix the return 1, though. That will only return out of the eval, not out of the sub.

      It still stuck, not alarmed for some reasons. My code right now has become:
      sub process_scheme{ my ($output_file) = @_; open (OUTPUT_FILE, ">", $output_file) || die "cannot open log file +"; my $scheme_pid = open (SCHEME, "./t.pl | ") || die "cannot pipe sc +heme"; my $str = ""; MAIN: while (1) { eval{ local $SIG{ALRM} = sub { die "alarm\n" }; # NB: \n require +d alarm 5;#$allow_time; if (eof(SCHEME)){ close OUTPUT_FILE; close SCHEME; last MAIN; } $str = <SCHEME>; alarm 0; }; if ($@) { close OUTPUT_FILE; kill $scheme_pid; close SCHEME; return -$current_player; } # process the line print OUTPUT_FILE $str; } return 1; }
      where the t.pl is
      while(1){};
      The script gets stuck, waiting forever, not stopping/returning anything
        kill $scheme_pid;

        You probably meant something like

        kill INT => $scheme_pid;

        As you have it, kill would try to send the signal number $scheme_pid to no processes — so nothing happens, effectively...

        As a result, your code hangs in the implicit wait behind close SCHEME, because the child process is still alive.

        what makes you think it's stuck? Are you sure it's really stuck and that you're not suffering from buffering? Add
        OUTPUT_FILE->autoflush(1);
        after the open. You'll need
        use IO::Handle qw( );
        at the top.