> -----Original Message-----
> From: Paul D. Kraus [mailto:[EMAIL PROTECTED] 
> Sent: Monday, May 09, 2005 9:19 AM
> To: Perl Beginners List
> Subject: Fork - Process ID
> 
> 
> Sceniro.
> I have many cron jobs that run perl scripts. These perl 
> scripts launch TbredBasic Applications. The problem I keep 
> finding these processes hung but I have noway of finding out 
> which program is actually causing the problem. When the 
> tbredbasic application launches the processes name is always BASIC.
> 
> I wanted to write a program that would write out the process 
> id and the perl program that spawned it to a file then 
> destroy that file when the program fails. This way I can just 
> look at the "log" and see that program X is what keeps hanging.
> 
> So I have been experminting with the fork command but I am 
> confused as to the out put I get. Below is the code and its 
> output follows. First please explain why the pid prints twice 
> and second let me know if there is a better way to achive 
> what I am trying to do.
> 
> TIA
> Paul
> 

Hi Paul.  Fork is fun to play with!

I've put some comments below:

> #!/bin/perl
> 
> use strict;
> use warnings;
> 
> defined( my $pid = fork ) or die "Cannot fork: $!";

  # right here, there are two processes running.  The first one, and the
one that got forked.
  # both processes have the $pid variable.  The original process should
receive the new processes
  # PID as the return value from fork, so it's $pid = 1111 (or, whatever
the system returns).
  # The new process will receive a 0 (zero) from fork.  Now you can use
that $pid value to split
  # your code down two different paths.

> print "pid:$pid\n"

  # When I ran your code, the following was printed:
  #  pid: 1275
  #  pid: 0
  # Your output was not included in the email.  Was your output
different than this?

> unless( $pid ) {
>   exec "date";
>   die "cannot exec date: $!";
> }

  # This unless block should run date command if the process is the NEW
process.  The old process
  # with a 0 (zero) value for $pid, will skip the 'exec' and 'die' lines
of code.  Is that what you intended?



Here is a subroutine template I use in my daemon scripts, if it helps.
The 'setsid' function requires that you import the POSIX module
somewhere in your code:

use POSIX 'setsid';

sub daemonize {
  # A forked process usually doesn't want to be in some random
directory, so we change to root (/)
  chdir '/' or die "Can't chdir to /: $!";

  # The forked process doesn't want to read from standard-in, nor do we
want it to spam the 
  # standard-out with random messages.
  open STDIN, '/dev/null' or die "Can't read /dev/null: $!";
  open STDOUT, '/dev/null' or die "Can't write to /dev/null: $!";

  # Here is where the actual fork takes place
  defined( my $pid = fork ) or die "Can't fork the daemon: $!";

  # Here the script that starts the forked process will end
  exit if $pid; # original (terminal) process dies here

  # This will give the forked process it's own session and make the
process it's own session leader
  setsid or die "Can't start a new session: $!";

  # finally, we'll duplicate standard-error to wherever standard-out is,
again to prevent spamming standard-out
  open STDERR, '>&STDOUT' or die "Can't dup STDOUT: $!";
}


Hope this helps you some.

--Errin



--
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