day dreamer
day dreamer

Reputation: 55

Killing an child process run through system() function in infinte loop is not working in perl

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

Answers (1)

mob
mob

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

Related Questions