in reply to Forking and loops: A plea for understanding.

The fork() doesn't know anything about the while loop. It simply copies the current process completely and returns the pid to the original process and 0 to the child process.

In your example, that means that it reloops in the original process and executes the rest of the loop in the child process. If there wouldn't be an exit() at the end of the loop, then the child would also start at the beginning of the loop again.

Maybe it's clearer written like this:

while(my $client = $server->accept()) { my $pid = fork; if (!defined $pid) { die "Could not fork()\n"; } elsif ($pid == 0) { # random # client # handling # stuff exit; } }
Liz

Replies are listed 'Best First'.
Re: Re: Forking and loops: A plea for understanding.
by BUU (Prior) on Aug 31, 2003 at 18:44 UTC
    I understand that it creates a copy and returns 0/pid depending on which branch you are in. I also understand that the parent just continues the loop while the child exits at the bottom. My question was "how is this possible"? How can perl create a copy and then start executing in the middle of a a loop?
      Ah, ok. Well, Perl cannot do that. ;-)

      The magic in this is basically an Operating System feature, only found on *nixen, which is accessible with the C-function by the same name. Check out man fork.

      So, Perl doesn't almost doesn't do anything to fork itself, it just calls the C-function "fork()" and let's the Operating System do all of the work.

      Well, close. Since 5.6.0, Perl flushes all files opened for output before forking. And on Win32 systems, there is no such thing as a C-function fork(). There some magic is done by Perl, but since I don't know much about Win32 systems, I can't tell you anything about that.

      Hope this clears it up.

      Liz

      How can perl create a copy and then start executing in the middle of a a loop?

      I've to explain this in Unix term. There's no fork() on Windows; it's emulated on that OS, but I've no desire to know how.

      First, it's not a Perl thing, it's an OS thing. The Perl fork() just does some handy stuff for the programmer (like flushing buffers) and then calls the system's fork that does all the neat stuff. Second, to understand how fork works, you first have to understand a little what consists of a process.

      A process occupies several parts of the memory. There's the text segment, which is where the (binary) program is stored, and there's the data segment which contains the variable data of a process. This is the part that changes during the lifetime of a process. (Lots of handwaving here, in reality most OSses have more segments, but that's not important now). There's also a program counter, a little pointer that's used to keep track where the process is in the execution of the program. For sake of the argument, consider the program counter to be in the data segment. Note that for the case of a Perl program, it's perl, the binary, that is in the text segment, and the (compiled) Perl program that's in the data segment - so the entire Perl program is copied.

      Now, what happens at a fork? The OS creates a new process; the child. The child *shares* the text segment, but the data segment is copied. (The latter is usually implemented using copy-on-write, but that's just a technique to delay the copying, the program won't notice it). This includes the program counter! So, both the child and the parent continue at the same point in the program after a fork. Only the return value is different. Perl doesn't start executing in the middle of a loop - it was still there!

      Note that the above was a simplied version of what really happens. What really happens will differ from Unix flavour to Unix flavour, but many of those details aren't noticeable for most programmers.

      Abigail