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

This code download EPG with xmltv grabber and send commands to tvtime (tvtime-command) to display a message (Wait several minutes while EPG updates...) along the bottom of the OSD. If program tvtime does not running, is useless to display a message in tvtime and i want to stop parent process (send commands to tvtime), without killing child (EPG updates...) and if tvtime will be open later while child not finished (EPG updates...), restart parent process (send commands to tvtime).
use strict; use warnings; use File::Temp qw(tempfile); $tmp = new File::Temp( UNLINK => 0 );; defined(my $pid = fork) or die "Couldn't fork: $!"; #child process if ($pid == 0) { system("tv_grab_fi | tv_sort >> $tmp"); my $HOME = $ENV{HOME}; system("mv $tmp $HOME/.xmltv/EPG.xml"); unlink($tmp); exit; } use POSIX qw(:sys_wait_h); #parent process while (! waitpid($pid, WNOHANG)) { system("tvtime-command DISPLAY_MESSAGE \'Wait several minutes whil +e EPG updates...\'"); sleep 1; }
Thanks. Here is my not smartly solution:
#parent process while (! waitpid($pid, WNOHANG)) { my $status = system("ps aux | grep \[tv\]time"); if (! $status) { system("tvtime-command DISPLAY_MESSAGE \'Wait several minutes + while EPG updates...\'"); sleep 1; } }

Replies are listed 'Best First'.
Re: PERL: stop and restart parent process without killing child
by Eliya (Vicar) on Jan 07, 2012 at 11:38 UTC
    ...later while child not finished (EPG updates...), restart parent process

    Problem is, you can't do any "re-parenting" of processes, and only parents can waitpid for their children. Hence, your while (! waitpid($pid, WNOHANG)) {...} loop would no longer work or make sense with a new process...

    Personally, I would just divide the task into two separate programs, the EPG updater and a monitoring process. The latter checks periodically via kill 0, $pid_of_EPG, or the existence of some flag file, etc. whether the EPG process is still running.

Re: PERL: stop and restart parent process without killing child
by zentara (Cardinal) on Jan 08, 2012 at 10:28 UTC
    I would just divide the task into two separate programs,

    Another alternative would be to switch to threads. Put the code that used to be your parent, into a thread, and you can halt the thread, then reuse or restart it with fresh virgin data.


    I'm not really a human, but I play one on earth.
    Old Perl Programmer Haiku ................... flash japh
Re: PERL: stop and restart parent process without killing child
by locked_user sundialsvc4 (Abbot) on Jan 10, 2012 at 14:48 UTC

    It is often a good idea, in such situations, to employ three threads/processes, not two:

    1. The user-interface (“main”) thread, which among other things monitors the other two threads and periodically updates the user display.   This is the only one of the three that has any direct dealings with the user.
    2. The interface to tvtime.
    3. The interface to EPG updates.
    • (There may be, as the case dictates, other “manager” or “intermediary” processes also involved, all ultimately owned by the main.   Many topologies are obviously possible.)

    If you want the tvtime process to stop updating something, just have the parent by some means send an urgent instruction to it, that it should do so.   The child receives the instruction (accepting it upon arrival in preference to whatever it had been doing), acknowledges it, and obeys it.   This child now obediently “does nothing” until it receives a countermand from its parent.   (But the operating system has not placed it into a “suspended” state ... unless of course you find it convenient to simply give the parent the prerogative to instruct the OS to do so.)   Perhaps the parent also sends a notification to the other process, giving it “the heads up” that its sibling is temporarily off-duty.