Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > fork()-ing questions

Reply
Thread Tools

fork()-ing questions

 
 
Monty
Guest
Posts: n/a
 
      02-21-2007
In researching the Perl fork() command, I've come across many examples
of code and have been able to ascertain that when fork() is called,
the parent process retains it's own PID wil the child process takes a
PID of 0, at least in relation to the parent process.
This is pretty simple to see and understand, except for the
understanding that the process invoking fork() creates a clone of
itself, in which case the code examples I see leave one thing
unexplained. Take for instance the basic fork() routine similar to
what I've found on the web:

$pid = fork();

if ($pid == 0) {
# Then I'm the child process
} else {
# I'm the parent process
}

Programmatically correct considerations aside (I know I should include
an exit for the child process), I'm wondering--if the child process is
a clone of the parent--why the child process doesn't execute the "$pid
= fork()" statement. Is there some limitation to the amount of code
that gets "cloned"?

Secondly, I see a code snippet out there that confuses me and I'd just
like clarification of what it's saying. The following line:

unless ($pid = fork()) {
# Do something as the child process
}

'unless' is, as I understand it, used to loop when a condition is
false. False, in Perl, is the value 0 (along with undef and the empty
string). What is this the result of this fork() and it's effect on
the 'unless' statement? If the fork() produces a child process, then
doesn't the result of the entire '$pid = fork()' statement produce a
true value, as in the call to fork() executed correctly? If it did,
then doesn't the 'unless' statement test as true, meaning the loop
code gets bypassed?

It's all very confusing. Any clarification on this would be
appreciated.

 
Reply With Quote
 
 
 
 
Darren Dunham
Guest
Posts: n/a
 
      02-21-2007
Monty <(E-Mail Removed)> wrote:
> In researching the Perl fork() command, I've come across many examples
> of code and have been able to ascertain that when fork() is called,
> the parent process retains it's own PID wil the child process takes a
> PID of 0, at least in relation to the parent process.


Huh? No.

fork() is called once, but returns twice (in two separate processes).

The parent process has the same PID as the calling process. In that
process, the return code of fork() is the PID of the other process (the
child).

In the child process, a new PID is created and the return code of the
fork call is 0.

#!/usr/bin/perl
use warnings;
use strict;
print "Before fork, PID = $$\n";
my $code = fork;
print "After fork, PID = $$, fork returned $code.\n";

$ perl /tmp/fork.pl
Before fork, PID = 26341
After fork, PID = 26341, fork returned 26342.
After fork, PID = 26342, fork returned 0.

> This is pretty simple to see and understand, except for the
> understanding that the process invoking fork() creates a clone of
> itself, in which case the code examples I see leave one thing
> unexplained. Take for instance the basic fork() routine similar to
> what I've found on the web:


> $pid = fork();


> if ($pid == 0) {
> # Then I'm the child process
> } else {
> # I'm the parent process
> }


> Programmatically correct considerations aside (I know I should include
> an exit for the child process), I'm wondering--if the child process is
> a clone of the parent--why the child process doesn't execute the "$pid
> = fork()" statement. Is there some limitation to the amount of code
> that gets "cloned"?


No. The return of fork() is different in the two processes. $pid is
not the PID of the process, it's the result of the fork() call.

> Secondly, I see a code snippet out there that confuses me and I'd just
> like clarification of what it's saying. The following line:


> unless ($pid = fork()) {
> # Do something as the child process
> }


> 'unless' is, as I understand it, used to loop when a condition is
> false. False, in Perl, is the value 0 (along with undef and the empty
> string). What is this the result of this fork() and it's effect on
> the 'unless' statement? If the fork() produces a child process, then
> doesn't the result of the entire '$pid = fork()' statement produce a
> true value, as in the call to fork() executed correctly? If it did,
> then doesn't the 'unless' statement test as true, meaning the loop
> code gets bypassed?


No. This is all in the first sentence of fork.

$ perldoc -f fork
fork Does a fork(2) system call to create a new process running the
same program at the same point. It returns the child pid to
the parent process, 0 to the child process, or "undef" if the
fork is unsuccessful.

> It's all very confusing. Any clarification on this would be
> appreciated.


Reread the fork documentation in perldoc and understand the difference
between the return value of a function and the PID of a process ($$).

--
Darren Dunham http://www.velocityreviews.com/forums/(E-Mail Removed)
Senior Technical Consultant TAOS http://www.taos.com/
Got some Dr Pepper? San Francisco, CA bay area
< This line left intentionally blank to confuse you. >
 
Reply With Quote
 
 
 
 
Monty
Guest
Posts: n/a
 
      02-21-2007
On Feb 21, 2:05 pm, Darren Dunham <(E-Mail Removed)> wrote:
> Monty <(E-Mail Removed)> wrote:
> > In researching the Perl fork() command, I've come across many examples
> > of code and have been able to ascertain that when fork() is called,
> > the parent process retains it's own PID wil the child process takes a
> > PID of 0, at least in relation to the parent process.

>
> Huh? No.
>
> fork() is called once, but returns twice (in two separate processes).
>
> The parent process has the same PID as the calling process. In that
> process, the return code of fork() is the PID of the other process (the
> child).
>
> In the child process, a new PID is created and the return code of the
> fork call is 0.
>
> #!/usr/bin/perl
> use warnings;
> use strict;
> print "Before fork, PID = $$\n";
> my $code = fork;
> print "After fork, PID = $$, fork returned $code.\n";
>
> $ perl /tmp/fork.pl
> Before fork, PID = 26341
> After fork, PID = 26341, fork returned 26342.
> After fork, PID = 26342, fork returned 0.
>
>
>
>
>
> > This is pretty simple to see and understand, except for the
> > understanding that the process invoking fork() creates a clone of
> > itself, in which case the code examples I see leave one thing
> > unexplained. Take for instance the basic fork() routine similar to
> > what I've found on the web:
> > $pid = fork();
> > if ($pid == 0) {
> > # Then I'm the child process
> > } else {
> > # I'm the parent process
> > }
> > Programmatically correct considerations aside (I know I should include
> > an exit for the child process), I'm wondering--if the child process is
> > a clone of the parent--why the child process doesn't execute the "$pid
> > = fork()" statement. Is there some limitation to the amount of code
> > that gets "cloned"?

>
> No. The return of fork() is different in the two processes. $pid is
> not the PID of the process, it's the result of the fork() call.
>
> > Secondly, I see a code snippet out there that confuses me and I'd just
> > like clarification of what it's saying. The following line:
> > unless ($pid = fork()) {
> > # Do something as the child process
> > }
> > 'unless' is, as I understand it, used to loop when a condition is
> > false. False, in Perl, is the value 0 (along with undef and the empty
> > string). What is this the result of this fork() and it's effect on
> > the 'unless' statement? If the fork() produces a child process, then
> > doesn't the result of the entire '$pid = fork()' statement produce a
> > true value, as in the call to fork() executed correctly? If it did,
> > then doesn't the 'unless' statement test as true, meaning the loop
> > code gets bypassed?

>
> No. This is all in the first sentence of fork.
>
> $ perldoc -f fork
> fork Does a fork(2) system call to create a new process running the
> same program at the same point. It returns the child pid to
> the parent process, 0 to the child process, or "undef" if the
> fork is unsuccessful.
>
> > It's all very confusing. Any clarification on this would be
> > appreciated.

>
> Reread the fork documentation in perldoc and understand the difference
> between the return value of a function and the PID of a process ($$).
>
> --
> Darren Dunham (E-Mail Removed)
> Senior Technical Consultant TAOS http://www.taos.com/
> Got some Dr Pepper? San Francisco, CA bay area
> < This line left intentionally blank to confuse you. >- Hide quoted text -
>
> - Show quoted text -


Ok, thanks. This is getting somewhat clearer. I wasn't aware of the
perldoc command and have been using the web to answer questions. That
first statement in the fork() docs helps.

My second question is still foggy, and I may not have asked it
correctly. Considering the statment 'unless ($pid = fork())', if the
fork is successful, then the entire '$pid = fork()' statement is
evaluated as true and the loop code gets skipped--which is ok in the
parent process. Then, if the perldoc is to be taken at its word, the
child process that gets forked only consists of the code following the
fork() statement, which in this case is the loop code. I see the
benefit of coding exits in child process code.

How am I doing so far?

 
Reply With Quote
 
anno4000@radom.zrz.tu-berlin.de
Guest
Posts: n/a
 
      02-21-2007
Monty <(E-Mail Removed)> wrote in comp.lang.perl.misc:
> In researching the Perl fork() command,


Did that research include reading "perldoc -f fork"? That would
be the starting point of any research.

> I've come across many examples
> of code and have been able to ascertain that when fork() is called,
> the parent process retains it's own PID


correct, so far.

> wil the child process takes a
> PID of 0, at least in relation to the parent process.


Where did you get that? The child gets its own PID, which fork
returns to the parent. fork() returns 0 to the child (that's how the
code can *tell* it is the child code). Otherwise, the child can
access its own pid via $$, it doesn't have to be told by fork().

There is no such thing as one PID "in relation" to another. PIDs
are integers, which are system-wide unique at any time, that's
their purpose.

> This is pretty simple to see and understand, except for the
> understanding that the process invoking fork() creates a clone of
> itself, in which case the code examples I see leave one thing
> unexplained. Take for instance the basic fork() routine similar to
> what I've found on the web:
>
> $pid = fork();
>
> if ($pid == 0) {
> # Then I'm the child process
> } else {
> # I'm the parent process
> }
>
> Programmatically correct considerations aside (I know I should include
> an exit for the child process), I'm wondering--if the child process is
> a clone of the parent--why the child process doesn't execute the "$pid
> = fork()" statement.


Because there is no child process when fork() is executed. The
parent process runs it for both. fork() *returns* twice, once to
the parent and once to the child, with different return values.

> Is there some limitation to the amount of code
> that gets "cloned"?


No, everything is cloned, but so is the point of execution. That
it, both continue immediately after fork() returns. Then they must
decide who is who.

> Secondly, I see a code snippet out there that confuses me and I'd just
> like clarification of what it's saying. The following line:
>
> unless ($pid = fork()) {
> # Do something as the child process
> }
>
> 'unless' is, as I understand it, used to loop when a condition is
> false. False, in Perl, is the value 0 (along with undef and the empty
> string). What is this the result of this fork() and it's effect on
> the 'unless' statement? If the fork() produces a child process, then
> doesn't the result of the entire '$pid = fork()' statement produce a
> true value, as in the call to fork() executed correctly? If it did,
> then doesn't the 'unless' statement test as true, meaning the loop
> code gets bypassed?


I think something is wrong about your mental model of what happens
with fork(). If my comments above (firstly) plus the lecture of
"perldoc -f fork" (mostly) don't help you set it right, I wouldn't
know what else to say. If they do help you understand fork(), I
think you will be able to answer the questions in the last
paragraph yourself.

Anno
 
Reply With Quote
 
Jürgen Exner
Guest
Posts: n/a
 
      02-21-2007
Monty wrote:
> Secondly, I see a code snippet out there that confuses me and I'd just
> like clarification of what it's saying. The following line:
>
> unless ($pid = fork()) {
> # Do something as the child process
> }
>
> 'unless' is, as I understand it, used to loop when a condition is
> false. False, in Perl, is the value 0 (along with undef and the empty
> string). What is this the result of this fork()


Depends. In the parent process it is the PID of the child and guaranteed to
be be different from 0. In the child process it is 0.

> and it's effect on
> the 'unless' statement?


Because only for the child process the condition ever evaluates to false the
body is only executed for the child process.

> If the fork() produces a child process, then
> doesn't the result of the entire '$pid = fork()' statement produce a
> true value, as in the call to fork() executed correctly?


But that is not what fork() returns. Did you check the documentation of
fork().

jue


 
Reply With Quote
 
Darren Dunham
Guest
Posts: n/a
 
      02-21-2007
Monty <(E-Mail Removed)> wrote:
>> $ perldoc -f fork
>> fork Does a fork(2) system call to create a new process running the
>> same program at the same point. It returns the child pid to
>> the parent process, 0 to the child process, or "undef" if the
>> fork is unsuccessful.


> My second question is still foggy, and I may not have asked it
> correctly. Considering the statment 'unless ($pid = fork())', if the
> fork is successful, then the entire '$pid = fork()' statement is
> evaluated as true and the loop code gets skipped--which is ok in the
> parent process. Then, if the perldoc is to be taken at its word, the
> child process that gets forked only consists of the code following the
> fork() statement, which in this case is the loop code. I see the
> benefit of coding exits in child process code.


Nope. Reread it again. fork() returns 0 to the child process. 0 is
not true. The unless gets the result of the assignment (0) in that case
and executes the conditional code.

That code is not testing for a successful fork (it would need to check
for definedness). Instead it is assuming a successful fork and checking
for parent or child.

--
Darren Dunham (E-Mail Removed)
Senior Technical Consultant TAOS http://www.taos.com/
Got some Dr Pepper? San Francisco, CA bay area
< This line left intentionally blank to confuse you. >
 
Reply With Quote
 
Monty
Guest
Posts: n/a
 
      02-21-2007
On Feb 21, 3:00 pm, Jim Gibson <(E-Mail Removed)> wrote:
> In article <(E-Mail Removed) .com>,
>
> Monty <(E-Mail Removed)> wrote:
>
> [program using fork snipped]
>
> > My second question is still foggy, and I may not have asked it
> > correctly. Considering the statment 'unless ($pid = fork())', if the
> > fork is successful, then the entire '$pid = fork()' statement is
> > evaluated as true and the loop code gets skipped--which is ok in the
> > parent process. Then, if the perldoc is to be taken at its word, the
> > child process that gets forked only consists of the code following the
> > fork() statement, which in this case is the loop code. I see the
> > benefit of coding exits in child process code.

>
> > How am I doing so far?

>
> You seem not to grasp that the call to fork(), if successful, will
> return two values: one to the parent and one the child. The parent
> value will be non-zero and therefore true, but the child's value will
> be zero and false. Therefore, the code in the unless block will be only
> executed by the child. Also, "unless" does not start a loop (you may be
> thinking of "until"). It is a one-time conditional, equivalent to "if
> not".
>
> The "child code" consists of everything inside the "unless" block, plus
> everything that follows that block unless and until the child executes
> an exit. The "child code" is the _same_ as the "parent code". It is up
> to your program to make each of them behave in an appropriate manner,
> using the return value from fork() to distinguish between them.
>
> Posted Via Usenet.com Premium Usenet Newsgroup Services
> ----------------------------------------------------------
> ** SPEED ** RETENTION ** COMPLETION ** ANONYMITY **
> ----------------------------------------------------------
> http://www.usenet.com


Believe it or not, I think I'm getting this. Thanks for to all for 1)
correcting me on understanding of 'unless'...it is not a loop
(somehow, I knew that, but I kept seeing a loop structure for some
reason), and 2) pointing me to perldoc (I've got those priorities
backwards, but I hope you get the drift).

I don't mean to belabor the point, but allow me to interpret that
whole 'unless' structure, one last time.

unless ($pid = fork()) {
# Child process code here
exit(0);
}
# Parent process code here

fork() spawns a new process consisting of code following the 'unless'
statement. The $pid variable gets populated with the child PID for
the parent version of $pid and populated with 0 for the child
(spawned) version of $pid (I thought I read that variables get copied
in a forked process). Since the fork was successful (assume success,
failure is a whole different matter), the statement '$pid = fork'
returns a non-zero value and is evaluated by the 'unless' statement as
true and does not execute the child process code. Terrific, that's
what was wanted. The child process executes the snippet of code
follwing the 'unless' statement until it hits the exit() statement. I
presume the child process attempts to return a value to the parent
process, but that's a matter better left for another conversation.

Without too much attention to detail, am I getting it?

 
Reply With Quote
 
Jürgen Exner
Guest
Posts: n/a
 
      02-21-2007
Monty wrote:
> unless ($pid = fork()) {
> # Child process code here
> exit(0);
> }
> # Parent process code here
>
> fork() spawns a new process consisting of code following the 'unless'
> statement.


No. The spawned process consists of exactly the same code as the parent
process.

> The $pid variable gets populated with the child PID for
> the parent version of $pid and populated with 0 for the child
> (spawned) version of $pid


Correct.

> (I thought I read that variables get copied
> in a forked process).


That is correct, too. However, those variables in the parent and child
process are totally independant of each other once the fork() is done. And
only at that moment does $pid is being assigned a value and this value
happens to be different for parent and child.

> Since the fork was successful (assume success,
> failure is a whole different matter), the statement '$pid = fork'
> returns a non-zero value


Correct for the parent, wrong for the child

> and is evaluated by the 'unless' statement as
> true and does not execute the child process code. Terrific, that's
> what was wanted. The child process executes the snippet of code
> follwing the 'unless' statement until it hits the exit() statement. I



Correct.

> presume the child process attempts to return a value to the parent
> process, but that's a matter better left for another conversation.


???

jue


 
Reply With Quote
 
Darren Dunham
Guest
Posts: n/a
 
      02-21-2007
Monty <(E-Mail Removed)> wrote:
> I don't mean to belabor the point, but allow me to interpret that
> whole 'unless' structure, one last time.


> unless ($pid = fork()) {
> # Child process code here
> exit(0);
> }
> # Parent process code here


> fork() spawns a new process consisting of code following the 'unless'
> statement.


I wouldn't say that. It spawns a new process that is identical (except
for the return of the fork call). So all code is duplicated, not just
the unless.

> The $pid variable gets populated with the child PID for
> the parent version of $pid and populated with 0 for the child
> (spawned) version of $pid (I thought I read that variables get copied
> in a forked process).


Variables are copied. Prior to the fork, the $pid wasn't assigned, so
it would have been 'undef'. So it is 'undef' in both (in some sense)
when the OS makes the copy. However immediately after the copy starts
running, it assigns the value of the fork() call to $pid.

So it is copied, but immediately overwritten afterward.

> Since the fork was successful (assume success,
> failure is a whole different matter), the statement '$pid = fork'
> returns a non-zero value and is evaluated by the 'unless' statement as
> true and does not execute the child process code.


$pid=fork returns a non-zero value if fork returns a non-zero value,
which is true in the parent only. This causes the parent to not execute
the code within the unless block. The child will execute the code in
the unless block.

While I do use unless in many situations in my code, it might be clearer
for you use additional statements and 'if' instead.

$pid = fork();
if ($pid == 0) {
# Child process code here
[...]

That might be clearer when you're trying to remember what fork returns
and reverse the sense of the if because it's an unless...

> Terrific, that's
> what was wanted. The child process executes the snippet of code
> follwing the 'unless' statement until it hits the exit() statement. I


Right.

> presume the child process attempts to return a value to the parent
> process, but that's a matter better left for another conversation.


The child doesn't attempt to do anything that's not in code.

However, I suggest you examine the 'wait' function if you're interested
in simple messages from the child to the parent.

> Without too much attention to detail, am I getting it?


Unfortunately, the computer is all about detail.

--
Darren Dunham (E-Mail Removed)
Senior Technical Consultant TAOS http://www.taos.com/
Got some Dr Pepper? San Francisco, CA bay area
< This line left intentionally blank to confuse you. >
 
Reply With Quote
 
Tad McClellan
Guest
Posts: n/a
 
      02-22-2007
Darren Dunham <(E-Mail Removed)> wrote:
> Monty <(E-Mail Removed)> wrote:



>> presume the child process attempts to return a value to the parent
>> process, but that's a matter better left for another conversation.

>
> The child doesn't attempt to do anything that's not in code.
>
> However, I suggest you examine the 'wait' function if you're interested
> in simple messages from the child to the parent.



And see the perlipc.pod manpage if you're interested in
more than "simple" messages.


--
Tad McClellan SGML consulting
(E-Mail Removed) Perl programming
Fort Worth, Texas
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Few Questions (HW questions already answered by me) padh.ayo@gmail.com C Programming 10 12-06-2006 05:48 PM
Malloc and free questions - learner questions pkirk25 C Programming 50 10-04-2006 02:22 PM
Questions on Canon 300D and etc. questions regarding digital photography Progressiveabsolution Digital Photography 12 03-24-2005 05:18 PM
Newbie questions - Couple of VC++ questions regarding dlls and VB6 Ali Syed C Programming 3 10-13-2004 10:15 PM
Re: Questions....questions....questions Patrick Michael A+ Certification 0 06-16-2004 04:53 PM



Advertisments