Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Forked off!

by larryk (Friar)
on Aug 06, 2001 at 20:13 UTC ( [id://102490]=perlquestion: print w/replies, xml ) Need Help??

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

I don't understand how the principal of something can make so much sense yet when I look at the code my brain just goes *fork... unexpected EOF!*. I have read perldoc perlfork and I understand (at least I think I do) about Win32 fork emulation, pseudo-processes, threading etc. but the code my $pid = fork or die - what does that fork actually do?

How does the fork syntax work? What code is actually executed by the fork? Has anyone got any example code that even I can understand - perhaps with a parent and a child taking it in turns to print "Hello, World!" or something?

help, please, larryk

   larryk                                          
perl -le "s,,reverse killer,e,y,rifle,lycra,,print"

Replies are listed 'Best First'.
Re: Forked off!
by tachyon (Chancellor) on Aug 06, 2001 at 20:29 UTC

    Fork splits split your code into two separate processes. Or in laymans terms we clone our program. Both the parent and child get *identical copies* of data structures and continue processing from the point immediately after the fork.

    The return value is undefined if fork fails. The return value from fork for the child process is zero, and the retrun value from fork for the parent process is the process ID of the child - ie not zero. We use the returned process ID value within a script that forks to decide who we are - parent or child?.

    One use is to fork off a child to do some time consuming task while allowing the parent to get on with what it was doing. Fork is the essence of parallel processing on modern Operating Systems. Active State Perl for Win32 has supported fork() at least since Build 614 I am told by crazyinsomniac.

    defined(my $pid = fork) or die "Can't fork $!"; # we now have two scripts running in parallel print "I am the child\n" if $pid == 0; print "I am the parent\n" if $pid != 0; # this is another way to determine who we are if ($pid) { # do parent stuff print "Do as I say!\n"; } else { # do child stuff print "I am not deaf, I'm ignoring you!\n"; }

    See this thread my children are driving me crazy!. The info is similar but I just love the title!

    Update

    Here is a really silly script that demonstrates the two processes operating on completely different wavelengths ;-) If you want the parent to terminate the child process after the "You're grounded!" uncomment the kill.

      The child process has a process ID of zero, and the parent process has a process ID of not zero.

      Not quite. The return value from fork is zero for the new (child) process (because it can get the parent's process ID via getppid) while the return value from fork for the old (parent) process is the (non-zero) process ID of the child.

      Both parent and child share data structures

      They each get their own copy of the data structures, so they don't really share them. For efficiency reasons, most implementations of fork will actually allow the parent and child to share the data structures until one process tries to modify a data structure. At that point, the copying is done (of the page(s) of memory containing the data that was trying to be modified).

              - tye (but my friends call me "Tye")
(jeffa) Re: Forked off!
by jeffa (Bishop) on Aug 06, 2001 at 20:22 UTC
    I am not familar with forking on Win32 - but here is a very simple script that demonstrates simple forking:
    print "My PID is $$\n"; my $child = fork(); # at this point, two scripts are executing simultaneously # fork spawns a new copy of the script, and returns the # process id of the parent to the parent, and 0 to the child if ($child > 0) { # this is the original (the parent) print "Hello Parent (PID is $$)\n"; } else { # this is the forked copy (the child) print "Hello Kid (PID is $$)\n"; }
    You can use getppid() inside the kid process to get the process ID of the parent if neccessary.

    Hope this helps

    jeffa

Re: Forked off!
by arturo (Vicar) on Aug 06, 2001 at 20:24 UTC

    As for the syntax, it would probably help to read the fork manpage for that. Pay particular attention to what the manpage says about the return value, since that's what drives the syntax here.

    In general, my $foo = function_call() or die makes a call to function_call and puts the return value of that call into $foo. $foo is then evaluated; if it turns out true, the or die never gets called, and if it turns out false, it does. Same thing, by the way, with open FILE, $filename or die except that one usually wants to keep the return value of a successful fork since that's the ID of the child process.

    HTH!

    perl -e 'print "How sweet does a rose smell? "; chomp ($n = <STDIN>); +$rose = "smells sweet to degree $n"; *other_name = *rose; print "$oth +er_name\n"'
Re: Forked off!
by arhuman (Vicar) on Aug 06, 2001 at 20:24 UTC
    How does the fork syntax work ?

    Simply : fork() duplicate a program into 2 which continues to execute in 2 different processes,
    from the fork() instruction.

    fork() return the child's process id (a positive integer) in the father's process and return 0 in the child's process
    (and this return value is mainly used to discriminate the child from the parent to branch accordingly...)

    UPDATE : I forgot to mention the undef value returned by a fork it failed...

    "Only Bad Coders Code Badly In Perl" (OBC2BIP)
Re: Forked off!
by jepri (Parson) on Aug 06, 2001 at 20:33 UTC
    Fork creates and runs a new instance of your program, just like if you ran it, except that the second program is a carbon copy of the first, at the point the fork occurs.

    The program forks at the $pid=fork and suddenly there are two programs running, both doing the next statement (the if). The only difference is that one will have $pid = 0 and one will have $pid = 1234 or some number, being the pid of the child.

    my $pid; $pid = fork; if ( $pid ) { #We are the parent print "Successfully forked, I am the parent\n"; } else { if ( $pid == 0 ) { #We are the child print "Successfully forked, I am the child\n"; } else { #undef value - no fork happened print "Fork failed for some strange reason\n"; } }

    I'm currently writing a module to do this and handle IPC as well. If you can hold on a few days I'll clean up the module and post it.

    ____________________
    Jeremy
    I didn't believe in evil until I dated it.

      I am interested to see your module when you finish it. Can you let me know when it's done? Also, if I fork inside a block, does fork only dup-up code to the end of the block?
         larryk                                          
      perl -le "s,,reverse killer,e,y,rifle,lycra,,print"
        Yes, I'll be sure to let you know (I'll be sure to let everyone know).

        And nope, fork duplicates the entire program. It's heavily optimised, so it doesn't copy to whole program immediately, but you efectively have two separate programs that can go their own separate ways.

        ____________________
        Jeremy
        I didn't believe in evil until I dated it.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://102490]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others studying the Monastery: (4)
As of 2024-04-20 00:51 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found