Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Re^5: Timeout and kill

by Eliya (Vicar)
on Mar 21, 2012 at 02:33 UTC ( [id://960706]=note: print w/replies, xml ) Need Help??


in reply to Re^4: Timeout and kill
in thread Timeout and kill

...but one way is to capture the process ID from the shell:

$pid = `command && echo $$` ;

This wouldn't work.

First (and least relevant), backticks interpolate the $$, so you'd get the PID of the Perl process here.  But even when fixing this using \$\$, you'd still not get the PID of the command, but that of the shell. And killing the shell does not necessarily also kill the command.  You could in theory try to fix the latter problems by using exec, i.e.

$pid = `echo \$\$ && exec command` ;

However, that still wouldn't work, because you wouldn't get at the $pid before the entire backticks command completed.  And in case of a timeout (where you would need the PID primarily), you'd get nothing at all:

#!/usr/bin/perl -w use strict; my $pid; local $SIG{ALRM} = sub { die "Timeout (pid=$pid)\n"; }; my $command = "perl -e '<>'"; alarm 5; eval { $pid = `echo \$\$ && exec $command`; }; print $@; alarm 0; print "pid=$pid\n"; __END__ Use of uninitialized value $pid in concatenation (.) or string at ./96 +0632.pl line 7. Timeout (pid=) Use of uninitialized value $pid in concatenation (.) or string at ./96 +0632.pl line 18. pid=

P.S.: contrary to what is implied elsewhere in the thread, alarm does by default not kill the subprocess behind the backticks in case of a timeout — as can easily be verified using ps.

Replies are listed 'Best First'.
Re^6: Timeout and kill
by nelson64 (Initiate) on Mar 23, 2012 at 01:53 UTC
    I am still struggling very much with killing the process once it has timed out. This is what I have:
    sub runFile2 { local($fileName, $timeout) = @_; my $child_pid; local $SIG{ALRM} = sub { $didTimeout=1; print OUTPUT "timeout"; print OUTPUT "-", $child_pid; kill 9, $child_pid; }; if ($child_pid = fork ) { # create child $didTimeout=0; alarm $timeout; $start=gettimeofday(); waitpid($child_pid, 0); # Wait for child to terminate alarm 0; $end=gettimeofday(); if($didTimeout==0) { print OUTPUT $end - $start; } else { kill 9, $child_pid; } } elsif (defined $child_pid) { $cmd = "$solver1 $fileName >> output.txt"; exec ($cmd); exit; } else { # Something terrible has happened, as fork failed die "Cannot fork!\n"; } }
    It may not be the best way because I've just been trying anything I can find. The code will timeout the function, but not kill it. Any suggestions? Help would be greatly appreciated. I've tried everything I can find online without success. Thanks!
      Oops I posted the wrong version of the code:
      sub runFile { local($fileName, $timelimit) = @_; my $child_pid; local $SIG{ALRM} = sub { $didTimeout=1; print OUTPUT "timeout"; print OUTPUT "-", $child_pid; kill $child_pid, 9; }; if ($child_pid = fork ) { # create child waitpid($child_pid, 0); # Wait for child to terminate } elsif (defined $child_pid) { alarm $timelimit; $cmd = "time $solver1 $fileName >> output.txt"; exec ($cmd); alarm 0; exit; } else { # Something terrible has happened, as fork failed die "Cannot fork!\n"; } }
      This code times out the function but allows it to still run in the background.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://960706]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others pondering the Monastery: (8)
As of 2024-04-23 19:09 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found