Hi,

Hello :)

I've been lurking on this thread for a bit, and now that you've jumped to children and 
fork and related topics I'll chime in!

I found a lot of useful information about this sort of thing in "perldoc perlipc".  
Check out the stuff about Daemons and the REAPER subroutine in that doc.  Also, in the cookbook 
(I think! I don't have it with me to check) there is some good stuff about daemons and children.

More specifically to the questions above, two things to be careful of:

First, always, ALWAYS check (then, check again!) that you are not going to fork-bomb 
your system.  If your script, forks (now you have 2), then both of those fork again, 
'cause you have a bug in a loop somewhere (now you have 4) and so on (now there are 8) 
and so on (16 ... Can you see where this is goin?!), you will quickly bring your box 
to a screaching halt!

Second, (I'm assuming this is a UNIX-ey OS) make sure you read up on setsid and 
sys_wait_h in the POSIX (perldoc POSIX) module, as well as the builtin 'waitpid' 
(perldoc -f waitpid).  You might have to 'man' the equivelant to get meaningful 
documentation (like, 'man setsid').

When I fork a process, I like to make sure the child at least does the following: - chdir /
(it's rude for a random process to sit on a filesystem that might need to be unmounted)
- change the stdin, stdout and stderr
(also rude to spurt random nonsense from a random process onto the terminal or somesuch)
- setsid
(So the child can own it's own session)


Like this:

sub daemonize {
        chdir '/'                       or die "Can't chdir to /: $!";
        open STDIN, '/dev/null'         or die "Can't read /dev/null: $!";
        open STDOUT, '/dev/null'        or die "Can't write to /dev/null: $!";

        defined( my $pid = fork )       or die "Can't fork the child: $!";

       #The exit below can be replaced with an if-else construct if you want the 
original to keep going.
       #I believe this has been handled in this thread already!
        exit if $pid;                   # original process dies here
        setsid                          or die "Can't start a new session: $!";
        open STDERR, '>&STDOUT'         or die "Can't duplicate STDOUT: $!";
}

I hope this helps a bit. Let me know if ya got more questions,

Very good info thanks, I'm learning a lot!

Since this isn't going to be a daemon (its a webpage that gives the visitor what they came for and then does some stuff on the server without them having to wait) and in conjunction with Bob's earlier suggetion (slightly modified):

#!/usr/bin/perl

use strict;
use warnings;
use CGI 'header';
use POSIX 'setsid';

defined(my $pid = fork) or die "Couldn't fork: $!";
if ($pid) {
    print header();
    print "Hello World\n";
} else {

  close STDIN;
  close STDOUT;
  setsid();

  # at this point your process is detached from the web server,
  # so start your long-running process now

  open FILE, '>> ./long.txt' or die $!;
  print FILE $$;
  sleep 3;
  print FILE ' ' . time() . "\n";
  close FILE;

}

What and were would you modify it to be safe? (the open stuff is just to take time up so we can see the original "web page" being out put and back to a prompt)

try it, its cool:
 ./long.pl
 tail -f long.txt

You'll see long.pl finishes running (putting you back to a prompt) and then the stuff is added to long.txt, very cool!

--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
<http://learn.perl.org/> <http://learn.perl.org/first-response>




Reply via email to