Reputation: 55
I have tried with simple program of infinite loop, I ran it using PERL script and tried to KILL it after sleep of 10, but my program is not killing the child-process and runs in infinite loop.
//C CODE: $cat loop.c
#include <stdio.h>
int main(){
while(1){
printf("Infinite loop\n");
}
return 0;
}
$ gcc loop.c -o loop.bin
// PERL CODE $cat timeout.pl
#!/usr/bin/perl
use strict;
use warnings;
use POSIX ":sys_wait_h";
use Time::HiRes qw(sleep);
if(!defined( my $pid = fork())) {
die "Cannot fork a child: $!";
} elsif ($pid == 0) {
print "Printed by child process\n";
system("./loop.bin");
} else {
print "Printed by parent process\n";
sleep(10);
my $ret = waitpid($pid, WNOHANG);
if ($ret == 0){
kill ('KILL',$pid);
sleep(1);
}
}
//OUTPUT: After execution the perl script is not killing the child process (./TC_1.bin) $ perl timeout.pl
Printed by child process
Infinite loop
Infinite loop
Infinite loop
Infinite loop
Infinite loop
Infinite loop
Infinite loop
Infinite loop
...
...
..
Upvotes: 3
Views: 373
Reputation: 118695
$pid
is the process id of the child process that was created by the fork
call. It is a perl process. When you call system($command)
, that creates a new process, running the command $command
, and you don't know what the process id of that command is. Calling kill('KILL',$pid)
sends a signal to the background perl process, but not necessarily to any of its children, so you can't be sure that the system
call will also receive the signal.
One solution is to use exec
instead of system
.
...
} elsif ($pid == 0) {
print "Printed by child process\n";
exec("./loop.bin");
} else {
...
exec
is like system
, but instead of launching the command in a new process, it replaces the existing process with a process running the command, preserving the process id. So after calling exec
, the child perl process will be gone, and $pid
will refer to the process running the command ./loop.bin
. Now you can signal $pid
and it will be sent to the desired process.
Upvotes: 5