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"
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.
| [reply] [d/l] [select] |
|
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")
| [reply] |
(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
| [reply] [d/l] |
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"'
| [reply] [d/l] [select] |
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)
| [reply] |
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. | [reply] [d/l] |
|
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" | [reply] |
|
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.
| [reply] |
|
|