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

Basically, I want to spam the screen with "yay" for one second then exit the program/stop the loop. I need to get fork to somehow work like this. Don't want some alarm() stuff that refuse to work on some platforms. This has a real use: I always try to get my new code to work before I put it to use.
if(fork){ while(1){print "yay"} } else { sleep(1); exit; }
Thanks

Replies are listed 'Best First'.
Re: Forking Issue
by chromatic (Archbishop) on Mar 17, 2001 at 10:46 UTC
    Your fork is backwards. To get this to work, you can send a signal to the child process with kill -- SIGTERM is a good choice. Someone more versed in signals on non-Unix platforms will have to correct my assumptions (I'm thinking of tye or AgentM on this one).
    if (my $pid = fork) { sleep 1; kill 9, $pid; wait; } else { while (1) { print "Yay!\n"; } }
    The wait may or may not be necessary, if you have automatic reaping. waitpid may be more appropriate.

    On the other hand, you could also use Time::HiRes and check to see if you've printed for enough ticks. That would relieve you of having to fork, especially on those platforms where you don't want to use alarm. (On Windows, I think it's implemented in the same manner as fork(), but again, someone who knows Perl on Windows will have to verify this.)

    Update: dkubb has provided cleaner and slightly more elegant code. I would use his in production.

      This example will not catch errors with fork. You first need to test if the returned $pid is defined or not:

      unless(defined(my $pid = fork)) { die "Could not fork: $!"; #fork failed } elsif($pid) { sleep 1; #parent kill 9, $pid; wait; } else { print "Yay!\n" while 1; #child }
      if (my $pid = fork) { sleep 1; kill 9, $pid; die("Shplah"); } else { while (1) { print "Yay!\n"; } }
      This should exit the program on-die, correct? It doesn't work. I get the little flashing cursor after the die message.
Re: Forking Issue
by $code or die (Deacon) on Mar 17, 2001 at 20:57 UTC
    how about:
    my $start = time; while (time < $start + 1) { print "yay"; }
    Ok - no fork, but it does what it needs - whatever that may be!

    $ perldoc perldoc

      Or if you're fussy about the time interval:

      use Time::HiRes qw(gettimeofday tv_interval); my $t0 = [gettimeofday]; while (tv_interval($t0) < 1.23) { print "Yay!\n"; }

      I appreciate that, but if a simple time trick would do the job of the real code, I would have done that. But as I said in the original post, "I need to get fork to somehow work like this."
        Why does it need to be fork? The Run commands in parallel works on both Windows and *nix (where fork is somewhat less portable). Will that do for your (unspecified) real task?