Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations wOOdy-Soft on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

EXEC delayed returning PID

Status
Not open for further replies.

MattGranger

Programmer
Jun 20, 2005
5
GB
Hi, This is my first Perl project, and it's proved to be challenging. I'm trying to spawn off a number of child processes, record their PID's, and then later use that PID to kill the process off if it's been running past a given length of time. Easy eh? Use FORK eh? Wrote a test child, and set it to sleep for 45 seconds, but set it's timeout for 30. The parent process kept running OK, the child process ran OK. But the PID wasn't returned to the parent in the fork code until the child had completed execution, i.e. until after it's 45 second sleep, so I couldn't kill it off. I've considered using thread & detach, but thought forum guidance might yield the answer I seek. Here's the code snippet that launches the child:


sub runit {

# Grab the executable and the associated parameter line
my $which=shift;
my $params = shift;

FORK: {
if ($pid=fork()) {
return $pid;
# this is the parent, so return the pid
# everything below here is either the child or a very major
# system failure
}
elsif (defined $pid) {

if ($granularity) {log_message("Starting monitor $which $params");}
exec $which ." " .$params;
# shouldn't reach this unless exec fails
log_message("Failure starting monitor $which $params");
exit 0;
# exit, NOT return. We're the child process
}
elsif ($! == EAGAIN) {
sleep 3;
redo FORK;
}
else {
log_message("Fork failure starting monitor $which $params");
return 0;
}
}


Many thanks,

Matt
 
First point, please please please use code tags around code.
Second, I'm not sure what you've done and I haven't tested your code but here's a quick snippet that does roughly what you say you want:
Code:
#!/usr/bin/perl -w
use strict;
use diagnostics;
my $pid;
if($pid = fork()) {
  # Parent
  sleep 30;
  print "Parent finished sleeping, about to kill child $pid\n";
  `kill $pid`;
} else {
  # Child
  sleep 60;
  print "Child finished sleeping.\n";
}
If you run that you'll see that the child process never completes with it's message since it get's killed off.



Trojan.
 
Trojan,

Thanks for the points - first post on the forum, so my apologies for not using Code Tags.

I understand your code, and understand how that works. The problem that I have is that the if($pid = fork()) doesn't execute until it appears that control is returned from the child process instigated by the exec statement.

Matt
 
If that were the case then my child process would print "Child finished sleeping". It does not.

Try my example and add as much debug as you like (print statements) to see what's happening and where.

I think you either misunderstand your code or something else is influencing the outcome.





Trojan.
 
Matt,

You're not on a Wintel box by any chance are you?

Mike

You cannot really appreciate Dilbert unless you've read it in the
original Klingon.

Want great answers to your Tek-Tips questions? Have a look at faq219-2884

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top