Connecting Tech Pros Worldwide Forums | Help | Site Map

Perl problem to add timeout for external calls on Win32

Newbie
 
Join Date: Dec 2007
Posts: 1
#1: Dec 7 '07
Hi,

I need to add a timeout for external programs, as the external program sometimes never dies (it's a ClearQuest multisite call to the shipping server, that sometimes never ends, but simply hangs).

I have three different ways of forking the call, but none works. I send the one I believe most in...

Expand|Select|Wrap|Line Numbers
  1. use POSIX ":sys_wait_h";
  2. my $loop      = 1;
  3. $loop           = $ARGV[0] if defined $ARGV[0];
  4. my $timeout = 10;
  5. my $child     = fork();
  6. unless ( $child )  {
  7.     # Child
  8.     exec( "perl count.pl $loop" );
  9.     exit 0;
  10. }
  11.  
  12. sleep( $timeout );
  13. my $kid = waitpid( $child, WNOHANG );
  14. if( $kid != -1 )  {
  15.     print "The child is still running! Kill the process: $child...\n";
  16.     kill( 9, $child );
  17. }
  18. else  {  print "no timeout\n";  }
  19.  
  20.  
The external program count.pl, is simply a program that prints an iterator every second:

Expand|Select|Wrap|Line Numbers
  1. my $loop     = 1;
  2. my $iterator = 1;
  3. $loop          = $ARGV[0] if defined $ARGV[0];
  4. for( ; $iterator <= $loop ; $iterator++ )  {
  5.    sleep( 1 );
  6.    print "$iterator($$)...\n";
  7. }
  8.  
  9.  
The idea is fine. After ten seconds, the mother process detects that the child process is still running, and tries to kill it.

And here is the strange thing!!!

The $child value (returned from the fork() command), is not the same as the $$ in the child process!!!

That means that the kill command is trying to kill another process (which in this case doesn't exist).

If I open another command tool window, and type in: perl -e "kill( 9, <child pid> )"
the child is killed.

Am I doing something wrong?

I tried also:

Expand|Select|Wrap|Line Numbers
  1.  local $SIG{ALRM} = sub { die "alarm\n" };       # NB \n required
  2.     alarm 10;
  3.     $child_pid = fork();
  4.     if( $child_pid )  {
  5.     print "Child_pid = $child_pid\n";
  6.         $pid2 = waitpid( $child_pid, 0 );
  7.     }
  8.     elsif( $child_pid == 0 )  {
  9.     print "child pid= $$\n";
  10.         exec( "ratlperl count.pl $x" );
  11.     exit( 0 );
  12.     }
  13.  
I do get an alarm signal after the timeout, but I don't have the correct pid here also. kill() doesn't work.

Any help would be appreciated very much.

Cheers,
/Richard

numberwhun's Avatar
Site Moderator
 
Join Date: May 2007
Location: New Hampshire
Posts: 2,573
#2: Dec 7 '07

re: Perl problem to add timeout for external calls on Win32


When you are posting code in the forums, please be sure and use the proper code tags. They are required and as you can see from your post, I have modified your post to contain them.

Regards,

Moderator
Reply