in reply to Timeout and kill
There are various "issues" with your code — primarily the following two:
after the fork, you don't differentiate between the child and the parent process. This means you have two processes both doing the same thing (running the solver, etc.) — the child process with a $pid of zero, and the parent with a $pid unequal zero.
the backticks do fork/wait themselves under the hood, so the pid you're killing is not the solver process, as intended...
There are several ways to approach this. Personally, I'd probably use a piped open instead of the backticks. Something like this:
sub run_with_timeout { my ($cmd, $timeout) = @_; local $SIG{ALRM} = sub { die "Timeout\n"; }; my $out; if (my $pid = open my $pipe, "-|") { eval { alarm $timeout; @$out = <$pipe>; }; my $ok = $@ ne "Timeout\n"; alarm 0; if ($ok) { close $pipe; } else { kill 9, $pid; waitpid $pid, 0; } return $out; } else { exec $cmd; exit; } } my $out = run_with_timeout("$solver $file", $timeout); print defined($out) ? "output of solver:\n@$out" : "timed out";
P.S.: in case your solver command contains shell meta characters (such as 2>&1), it would be run via a shell. This means you'd have to modify the exec call to read:
exec "exec $cmd";
The second exec is executed by the shell, so it replaces itself with the solver command. It is required so that you kill the solver, not the shell.
|
|---|