Reputation: 121
I'd like to spawn a process, do something and kill it afterwards manually when I'm done.
It's not working though. The process starts, I see the pid and the while loop keeps running until I kill it.
Could it be, that Perl spawns a new shell which then spawns the UI process, which doesn't get killed by Perl when the shell (which Perl spawned) is killed?
my $cmd = "notepad.exe";
my $sleepTime = 10;#60 * 10;
$childPid = fork();
if ($childPid)
{ # Parent
print "Started child process id: $childPid\n";
sleep $sleepTime;
$SIG{CHLD} = 'IGNORE';
while (kill(15, $childPid))
{
my $numKilled = kill(SIGTERM, $childPid);
printf("numKilled: %s\n", $numKilled);
printf("numKilled: %s\n", $childPid);
sleep 1;
}
}
elsif ($childPid == 0)
{ # Child
system($cmd);
exit 0; # will never get here
}
else
{ # Unable to fork
die "ERROR: Could not fork new process: $!\n\n";
}
Upvotes: 0
Views: 575
Reputation: 126722
The Forks::Super
module provides many useful facilities for handling forked processes, as well as offering a more portable interface.
This program runs notepad
to edit the program's own source file and kills the child process after five seconds. If you need to pass parameters to the command then you should specify it as an anonymous array of values like this. If you use a single string like cmd => qq<notepad "$0">
instead then you will start a copy of cmd.exe which in turn starts notepad.exe, and the kill
command will just leave notepad running as an orphan
use strict;
use warnings;
use Forks::Super;
if ( my $pid = fork({ cmd => [ 'notepad', $0 ] }) ) {
sleep 5;
Forks::Super::kill('TERM', $pid);
print "Killed\n";
}
Note that if you want to apply a timeout to the child process then you can write
my $pid = fork({ cmd => 'notepad', timeout => 600 })
Upvotes: 1