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 strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Run subroutine in background on Windows

Status
Not open for further replies.

MoshiachNow

IS-IT--Management
Feb 6, 2002
1,851
IL
HI,

I need to run my subroutine in background,and timeout the sub after 120 seconds if it did not complete yet (got stuck somwhere in the middle...)
Read a lot of stuff on backgrounding on Windows,but can not make my mind on the simpliest way to go with this task.
Would appreciate advise.

(my current implementation does not work:

use Sys::AlarmCall;
alarm_call(120,'&processPDF',$myfile); #timeout of 2 minutes
)

thanks

Long live king Moshiach !
 
what do you mean by "got stuck somwhere in the middle"? do you mean die?...or if it takes too long because for example a file that it supposed to read is huge?

as I see it you have to make two processes...one to do the job and the other to count the time....when the time reach the limit, kill the main process and die.

maybe posting your code will be helpful for the people in this forum to give you a hand.


``The wise man doesn't give the right answers,
he poses the right questions.''
TIMTOWTDI
 
HI,

I did post my sample code above,and it does NOT timeout ...
The problem is to yimeout the sub processing some file which is too long or just bad.
thanks

Long live king Moshiach !
 
See what you can find out about using fork() and the %SIG variable. It's been years since I messed with this but in a nutshell here's what you can expect:
[ul]
[li]Parent process sets up interrupt subroutine under %SIG to be called when forked process (aka kid) exits.[/li]
[li]Parent process forks and then goes about it's business.[/li]
[li]Kid process does what it needs to taking care of its timeout / exit parameters.[/li]
[li]When kid-pid exits, have it trigger the %SIG interrupt. Kid-pid can now be considered as non-existent.[/li]
[li]Parent will see the interrupt and automatically jump to the subroutine set up in the corresponding %SIG.[/li]
[li]When parent reaches end of subroutine determined by %SIG, the subroutines 'return' statement will return you to the point in your code where you were interrupted from.[/li]
[/ul]
A couple of comments from what I remember getting everything to work cleanly:
- Use the my() construct. Nuff said.
- If kid-pid is waiting for an event, use the sleep() command between loops. Doing something like:
Code:
while ($i<$ten_gazillion) {
  (-f $file_im_looking_for) ? exit : ++$i
}
you'll eat up your cpu time and the parent process will nearly come to a stand still.
- Passing information between kid-pid and parent was a conundrum for me. I ended up either having the parent process re-assess the information or kid-pid would write what it knew to a pre-determined file and the parent would read that file back in.

I have some old code somewhere that I can strip down and supply an example. Its somewhere on a WinNT box I've got in the basement. I'll look for it this weekend.
 
The real problem is your on windows :) alarm works perfect or this on unix/linus. Forking on windows isn't any fun either (it works.. just different). I'll do some testing in a bit to see if there is any alarming that works on windows. Can you tell me if your using 5.10 or 5.8?

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[noevil]
Travis - Those who say it cannot be done are usually interrupted by someone else doing it; Give the wrong symptoms, get the wrong solutions;
 
HI,

travs69 , I'm using 5.8

PinkeyNBrain - thanks,I will exercise this direction.

My problem is that my KID sub is not waiting for file,but rather parsing it,and may get stuck for really long period,which I want to timeout after 2 minutes.

thanks

Long live king Moshiach !
 
HI,

Managed to created the following code that works:

use threads;
my $thr = threads->create(\&$subroutine, $myfile);
$thr->detach();
my $i = 0;
while ($thr->is_running()) {
select (undef,undef,undef,0.20); #sleep 0.20 seconds
$i++;
if ($i > 300) { #timeout in 1 minute
#$thr->kill('KILL');
print STDOUT "TIMED OUT !\n";
last;
}
}

The problem is that if I use $thr->kill('TERM') ,then it kill the main program,not the thread.Why would it be ?

Long live king Moshiach !
 
Never worked with threads, your solution may be better than what I have here. To ge a feeling for what is going on, try the following
Code:
$SIG{'INT'} = 'handle_int' ;
&parent_main();

sub parent_main {
   $i = 0;
   while ($i<5) {
      ++$i ;
      print "a>$i<\n"; sleep 1 ;
      print "b>$i<\n"; sleep 1 ;
      print "c>$i<\n"; sleep 1 ;
      print "d>$i<\n"; sleep 1 ;
   }
   return 1 ;
}

sub handle_int {
   print "signal seen>$_[0]<\n";
   return 1 ;
}
When you hit ^C, you'll see "signal seen>INT<" show up in the output, but the flow of execution in &parent_main is not otherwise interrupted. Now consider
Code:
$SIG{'INT'} = 'handle_int' ;
$childid = fork();
if ($childid) {
   &parent_main () ;
} else {
   &child_main () ;
} ;

exit 0 ;

sub parent_main {
   $i = 0;
   while ($i<5) {
      ++$i ;
      print "a>$i<\n"; sleep 1 ;
      print "b>$i<\n"; sleep 1 ;
      print "c>$i<\n"; sleep 1 ;
      print "d>$i<\n"; sleep 1 ;
      last if ($child_has_exited) ;
   }
   return 1 ;
}

sub handle_int {
   $child_has_exited = 1 ;
   print "signal seen>$_[0]<\n";
   return 1 ;
}

sub child_main {
   my($start_timer) = time ;
   while (($start_timer + 120) > time) {
      # parse file
   }
   kill 16, getppid() ;
   return 1
}
If I'm remembering correctly, this worked on a linux system. The 'kill 16' would send the 'INT' signal to the parent pid. I'm on the road right now and don't have access to my linux box to verify. I'm unable to get the above code to work on this XP box (Yes travs69, this is a real problem) The alterations I used to make this work on the NT box years back involve what I tend to referr to as Conan programming. It involved the child updating a common file. The parent would examine the file to see if the child was still alive, or needed to pass back info, or whatever.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top