I need to write a perl script to execute external programs and grab the output and return code. Each program should be killed if it has not completed within X seconds.
Imagine that the script goes something like this :
@commands = &get_commands();
foreach $cmd (@commands) {
$pid = execute($cmd, $timeout);
push (@pids, $pid);
}
# pid included above in case it's needed
&wait_for_completion_or_timeout;
foreach (@commands) {
if ($output{$cmd}) {
print "Output of $cmd was $output{$cmd}, it comleted in $duration{$cmd} seconds\n";
} else {
print "$cmd did not complete in the allowed time and was killed";
}
... what could the execute function look like ?
Currently I have something roughly like this
sub execute {
my $cmd = shift;
my $pid;
unless ($pid = fork) {
exec("$cmd > /tmp/out.$$");
}
return $pid; # returning this pid, just in case
}
This works, but I don't feel it's very elegant. I have to keep track of all pids and kill processes that take more than X seconds using 'ps' to track processes and 'kill' to kill them. Ideally I'd like something platform independent. I've looked into multi threaded programming but I'm unfamiliar with this and I'm stomped.
Example of my attempted code to achieve the same as above:
sub execute {
my $cmd = shift;
system("$cmd >/tmp/out.$$");
}
foreach $cmd (@commands) {
my $thread[$i++] = threads->create(\&execute,$cmd);
}
If I run this code I get an error like
A thread exited while 5 threads were running.
... where do I go from here ? How do I wait until each thread has completed, and how would I kill slow threads ?
Should I be looking at a completely different approach ?
Any assistance appreciated !