• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 528
  • Last Modified:

How to stop an external process after a user defined time

I need to kick off an external process either with back-tics or the system command (please compare that to the exec() I actuall try below -- is it the same result?), allow it to run for 5, 10, 100, or some other user def. minutes, then kill it in order to restart the process with a different set of inputs.

I imagine something like the code below, but I admit I have not tried it yet, since I'm at home.  Questions are, is this the best way?  Is this likely to work?  Anyone have a better solution?  Running a process for x minutes, then killing it seems like a common thing, but I find no examples that target that.

"my_process" will run indefinitely if it's not stopped, so I must figure out how to stop it after "user-defined" minutes, and then I still need to be able to start a new iteration and handle it the same way, till I'm done with all input sets...

if (!defined ( $kidpid = fork() )) {
    # fork returned undef, so failed
    die "cannot fork: $!";
}  elsif ($kidpid == 0) {
                # fork returned 0, so this branch is the child
    exec("my_process");
                # if the exec fails, fall through to the next statement
    die "can't exec my_process: $!";
}  else {
                # fork returned neither 0 nor undef,
                # so this branch is the parent
    sleep(1000);
    kill 9, $kidpid
}
0
mark_at_acc
Asked:
mark_at_acc
3 Solutions
 
ozoCommented:
Yes, your code should work.
0
 
mark_at_accAuthor Commented:
Thanks ozo, I think it *should* work too, but I was hoping for more feedback, other ideas (maybe this is not the only solution), possible gotchas with the code, etc.

My experience with writing (for me, it was usually "maintaining" and "fixing") forking code in C was that it is rarely as simple as it looks at first...
0
 
knel1234Commented:
mark,

Are you trying to monitoring something (ie System Performance, Database, webserver)?  I have done a few thing for persistent processes.  Regardless of wether the process is for a database or not, if you can connect to a database create a 1 row table that contains start time, stop time, frequency etc.  You can use the same code to update this row etc etc.  If you do not have a database to utilize the just make a flat file with tokens for start time, stop time, frequency etc.  Regardless, you can simply have your program poll this table (or flatfile) to determine wether continued processing or termination of the process (pid) is required.  
On the otherhand, I have also feed the result of ps -ef | grep <process_name> to verify my process was running so that I would not create multiple instantiation of my process (ps -aux | grep <process_name if you are in that world).  You could do this or have another function (or a sybling process) to terminate the existing one.  For example, if the user starts you original process call a function to determine the execution status.  If the process is running, then terminate and restart the process.  If the process was not executing then simply start the process.  Furthermore, if you have this addition process (or function) then simply call it to terminate the process (pid).  
Lastly, I know the 'kill 9 pid#' concept but It can occasion cause problems from zombie to worse.  If you have your process reference a table or flatfile to terminate you will definately have a 'cleaner' ending of your process

knel    
0
Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

 
mark_at_accAuthor Commented:
A.  I am in Win2000 land, cannot count on cygwin tools being available.

B. I am writing the script for a QA group, I am sticking to the requirements they gave:
   1.  they want to kick off my script with an imput file they will write, and a time like 60 minutes given at the command line.
   2.  My script starts their exe file, feeding it item 1 from their input file, run it for 60 minutes, kill it.
   3.  restart the exe, feeding it item 2 from their input file, run for 60 min, then kill it.
   4.  If no more entries are available from the input file, quit.
   5. log some data along the way.

So, it's length of time that matters, not time of day. a QA Rep will be happy to manually start the process, it's the repeated changes in input and the restart they need automated.  they also don't like to guess when they should stop the process, because they need benchmark data.
0
 
mark_at_accAuthor Commented:
Actually I have now tested my fork and exec.

The problem now is $kidpid contain a negative value like -1416, and the process it tries to kill has a pid in task manager like 1724.  So, the process doesn't get killed.

The rest of my code seems to work fine, except for the kill.  Any ideas?
0
 
CmdrRickHunterCommented:
I cannot speak for the perl interface with windows, but cygwin has to do some funky stuff to make pids work.
Cygwin PIDs are not the same as taskmanager pids.  C has functions to convert one into the other, hopefully perl has similar.

Look into cygwin-specific perl modules?  Anyone else want to pick it up from here?
0
 
mark_at_accAuthor Commented:
Win32::process is what I went with, I'll assign points, thanks.
0
 
mark_at_accAuthor Commented:
I gave knel1234 most points based on his volume of feedback, but no one really gave me the help I was hoping for.  Oh well, can't win em all, this question must have been too specialized in an area people usually don't have to code in.  Thanks for the feedback!  Mark
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now