Q:

Perl kill process with timeout ignored

I was testing my source code, in which the child process calls several other programs (some of which are C++). 
#Other variables and functions

my $MAX_TIME = 10;#testing 10 minutes
my $timeRemaining = $MAX_TIME * 60;
my $pid = fork();
if ( $pid == 0 ) {
  #child process
  my $nowTime = localtime;
  print "Run started at $nowTime\n";

  #This run() calls a for loop in perl, in each iteration there are several C++ programs
  run();

  setpgrp(0,0);
}
elsif ($pid > 0){
  my $nowTime = localtime;
  eval{
    local $SIG{ALRM} = sub {
      kill -9, $pid;
      print "Run completed at $nowTime\nJob time out for $MAX_TIME minutes\n";
      log();
      die "TIMEOUT!\n";
    };
    alarm $timeRemaining;
    waitpid($pid, 0);
  };
  print "Run completed at $nowTime with no timeout\n";
}

When I checked the print out, I noticed that after 10 minutes, the "Run completed at $nowTime with no timeout\n" part gets printed out, and the child process is still executing.  The die "TIMEOUT!\n"; part in the parent process does not get executed. 
Is it because of the C++ programs that the perl program calls cannot be killed once it started? 

A:

First of all, kill is failing because $pid isn't a process group. 
run();
setpgrp(0,0);

should be
setpgrp(0,0);
run();

Secondly, the reason you see
Run completed at $nowTime with no timeout

even when there's a timeout is that you execute
print "Run completed at $nowTime with no timeout\n"; 

whether there's a timeout or not. 

Thirdly, you don't disable the alarm when the child is reaped.  Add
alarm(0);

Fourthly, you expect $nowTime to contain the current time without making it so. 

Finally, you still need to reap your child even if you kill it. ( Ok, this can be skipped if the parent exits immediately anyway.) 

Fixed:
use strict;
use warnings;

use POSIX qw( strftime );

sub current_time { strftime("%Y-%m-%d %H:%M:%S", localtime) }

sub run {
  print("a\n");
  system('perl', '-e', 'sleep 3;');
  print("b\n");
  system('perl', '-e', 'sleep 3;');
  print("c\n");
}

my $MAX_TIME = 5;
my $pid = fork();
die($!)  if ! defined($pid);
if ($pid) {
  if (eval{
    local $SIG{ALRM} = sub {
      kill KILL => -$pid;
      die "TIMEOUT!\n";
    };
    alarm($MAX_TIME);
    waitpid($pid, 0);
    alarm(0);
    return 1;
  }) {
    print "[".current_time()."]  Run completed.\n";
  } else {
    die($@) if $@ ne "TIMEOUT!\n";
    print "[".current_time()."]  Run timed out.\n";
    waitpid($pid, 0);
    print "[".current_time()."]  Child reaped.\n";
  }
} else {
  print "[".current_time()."]  Run started.\n";
  setpgrp(0,0);
  run();
}

Output:
[2017-05-11 14:58:06] Run started. 
a
b
[2017-05-11 14:58:11] Run timed out. 
[2017-05-11 14:58:11] Child reaped.