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

hi,

i'm experiencing something strange here, maybe you guys can help me. that's the code:

#!/usr/bin/perl use strict; use POSIX ":sys_wait_h"; sub REAPER { 1 until waitpid(-1, WNOHANG) == -1 } $SIG{CHLD} = \&REAPER; my $run = 0; while (1) { my $pid = fork; if (defined $pid && $pid == 0) { # child my $gna; # demo workload, could be everything for ("aaaaa" .. "bbbbb") { $gna = uc $_; } exit; } else { sleep 1; $run++; print "\n$run\n"; } }

my approach was to create a parent process which increments the $run every second, regardless of the workload done by the child-process. unfortunately that doesn't work. it seems as if there was no sleep. can you help? what am i doing wrong?

everything i want is a parent that counts from 1 to whatever every second and a child to do the dirty work.

thanks in advance!

Replies are listed 'Best First'.
Re: fork() doesn't care about my sleep()?
by JavaFan (Canon) on Nov 10, 2010 at 23:41 UTC
    The child exits, with sends a signal to the parent. This causes the sleep() to be interrupted. You may want to use a sleep that does sub second timings, and inspect the return value of sleep, sleeping again if necessary.
      my $sleep = 1; $SIG{ALRM} = sub { $sleep = 0; }; $SIG{CHLD} = sub { ... child ends here ... }; ... if (... $pid == 0) { ... child here } else { $sleep = 1; alarm (1); wait_for_signal while $sleep; # search for POSIX, SigAction, ... }
Re: fork() doesn't care about my sleep()?
by BrowserUk (Patriarch) on Nov 11, 2010 at 00:13 UTC

    T'is easier with threads:

    #! perl -slw use strict; use threads; my $run = 0; while( 1 ) { async { my $gna; for ( 'aaaaa' .. 'bbbbb' ) { $gna = uc; } }->detach; sleep 1; printf "\r%d", ++$run; }

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

      thanks a lot for that hint with threading, that's really working for me!

      and thanks to alle the others too, you were really helpful! :)

Re: fork() doesn't care about my sleep()?
by locked_user sundialsvc4 (Abbot) on Nov 11, 2010 at 05:04 UTC

    Believe me...   the best way to approach “child processes|threads” is as though they were the now-college-age kids that you get a postcard from once a month IM from every five seconds and that you try your best not to seriously worry about in the meantime.

    Once you launch a child process or child thread to do some particular task, as a very-basic design principle do not seek to meddle in its affairs.   Do not design nor contemplate anything that is to the very slightest degree dependent upon any artifact whatsoever of “timing,” for as surely as such silly notions may (seem to) prove themselves in testing, forsooth ... they shall surely prove a fool of ye in actual production!

    Heh™ ...   “Abandon all hope, ye who enter here ...”

    P.S.:   The aforesaid admonition has nothing whatsoever in-particular to do with “Perl in-particular.”   It is a VNIVERSAL TRVTH ...

Re: fork() doesn't care about my sleep()?
by ikegami (Patriarch) on Nov 10, 2010 at 23:51 UTC
    use Time::HiRes qw( time sleep ); sub unint_sleep($) { my $sleep_til = time + $_[0]; for (;;) { my $sleep_dur = time - $sleep_til; last if $sleep_dur <= 0; sleep($sleep_dur); } }