Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I have a (closed source, proprietary, external) program with a tendency to stop working (not die - just quit doing things, likely due to network latency).

I want to write a short perl program that checks to make sure the program hasn't stopped. Since it writes to a several times a second (when working), I thought I could check the time of the file every second (with "sleep 1"), and if it differed from the current time by more than a second, kill the program and restart it.

Does the idea sound reasonable or does someone know a completely different (better) approach? I assume I would use "exec" (and not "system") to start the program. Does some easy way exist to get the process number to kill it? Any other pitfalls to avoid?

Replies are listed 'Best First'.
Re: Keeping a program running
by graff (Chancellor) on May 09, 2007 at 05:17 UTC
    I think you might get the best results using fork: the parent process spawns a child process (and has the child's pid); the child does an "exec ..." to run the external program in question. This makes sure that when the external program is running, it has the same pid as the child process that started it.

    The parent could check the age of the file, or check the size (with the "-s" operator -- see the -X section of the perlfunc man page), sleeping for maybe 3 or 5 seconds between checks. If the file hasn't grown since the last check, kill the child pid and start a new child. Continue doing that as long as you want.

    (Update: added link to docs for the "kill" function, to clarify that this is a built-in.)

      That looks like it will work very well.

      One question, though - how do I test for the parent versus the child (so I know to start the external program in the child and not in the parent)?

        That's covered pretty well in the referenced man page for fork: it returns undef on failure, zero in the child process, and the child's pid in the parent process.
Re: Keeping a program running
by chrism01 (Friar) on May 09, 2007 at 07:09 UTC
    As per this page : http://perldoc.perl.org/functions/fork.html, fork() "returns the child pid to the parent process, 0 to the child process, or undef if the fork is unsuccessful", so you can tell which 'copy' you are currently in, as it were ...
    Sort of like this
    # Fork new process $pid = ''; if( $pid = fork() ) { # Parent proc } elsif( !defined $pid ) { exit_with_error("Can't fork: $!"); } # ... else we are the child, call exec.
    Cheers
    Chris