Home > Archive > PERL Miscellaneous > February 2007 > fork()-ing questions
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
fork()-ing questions
|
|
|
| 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.
| |
| Darren Dunham 2007-02-21, 7:06 pm |
| Monty <dale.schmitz@offutt.af.mil> 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 ddunham@taos.com
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. >
| |
|
| On Feb 21, 2:05 pm, Darren Dunham <ddun...@redwood.taos.com> wrote:
> Monty <dale.schm...@offutt.af.mil> wrote:
>
> 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.
>
>
>
>
>
>
> 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.
>
>
> 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.
>
>
> 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 ddun...@taos.com
> 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?
| |
| anno4000@radom.zrz.tu-berlin.de 2007-02-21, 7:06 pm |
| Monty <dale.schmitz@offutt.af.mil> 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
| |
| Jim Gibson 2007-02-21, 7:06 pm |
| In article <1172090025.578027.306150@j27g2000cwj.googlegroups.com>,
Monty <dale.schmitz@offutt.af.mil> 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
| |
| Jürgen Exner 2007-02-21, 7:06 pm |
| 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
| |
| Darren Dunham 2007-02-21, 7:06 pm |
| Monty <dale.schmitz@offutt.af.mil> wrote:
[color=darkred]
> 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 ddunham@taos.com
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. >
| |
|
| On Feb 21, 3:00 pm, Jim Gibson <jgib...@mail.arc.nasa.gov> wrote:
> In article <1172090025.578027.306...@j27g2000cwj.googlegroups.com>,
>
> Monty <dale.schm...@offutt.af.mil> wrote:
>
> [program using fork snipped]
>
>
>
> 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?
| |
| Jürgen Exner 2007-02-21, 7:06 pm |
| 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
| |
| Jim Gibson 2007-02-21, 7:06 pm |
| In article <1172093424.575039.128370@j27g2000cwj.googlegroups.com>,
Monty <dale.schmitz@offutt.af.mil> wrote:
> 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);
> }
I suggest that since you are still having trouble grasping the cloning
process initiated by fork, you are better off coding the above as
follows (untested):
my $ret = fork();
print "In process $$, fork has returned $ret\n";
if( $ret ) {
print "parent process has spawned child process $ret\n";
my $pid = waitpid($ret);
print "child $pid has terminated with status $?\n";
}elsif( defined $ret ) {
print "child processing now executing as process PID $$\n";
# child processing goes here
exit(0);
}else{
die("fork failed: $!");
}
And the child doesn't return a value to the parent, but the exit status
of the child, normally zero, is captured by the system and may be
fetched by the parent as above. See 'perldoc -f waitpid' for details.
Posted Via Usenet.com Premium Usenet Newsgroup Services
----------------------------------------------------------
** SPEED ** RETENTION ** COMPLETION ** ANONYMITY **
----------------------------------------------------------
http://www.usenet.com
| |
| Darren Dunham 2007-02-21, 7:06 pm |
| Monty <dale.schmitz@offutt.af.mil> 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 ddunham@taos.com
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. >
| |
| Tad McClellan 2007-02-21, 10:03 pm |
| Darren Dunham <ddunham@redwood.taos.com> wrote:
> Monty <dale.schmitz@offutt.af.mil> wrote:
>
> 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
tadmc@augustmail.com Perl programming
Fort Worth, Texas
| |
| Michele Dondi 2007-02-22, 4:10 am |
| On 21 Feb 2007 13:30:27 -0800, "Monty" <dale.schmitz@offutt.af.mil>
wrote:
>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.
No, in general processes do not *return values* to each other,
parent-child relationship or not. That's why IPC techniques exist:
perldoc perlipc
Michele
--
{$_=pack'B8'x25,unpack'A8'x32,$a^=sub{po
p^pop}->(map substr
(($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^<R<Y]*YB='
..'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,$_,
256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,
| |
| Michele Dondi 2007-02-22, 8:05 am |
| On Wed, 21 Feb 2007 21:42:57 GMT, "Jürgen Exner"
<jurgenex@hotmail.com> wrote:
>
>No. The spawned process consists of exactly the same code as the parent
>process.
For the benefit of the OP: do not confuse the *source* code with the
code *in memory* for running processes. The latter contains *state*,
which in turn corresponds to the execution point of your program. Now,
when you fork() a child process is created that is a perfect copy of
the parent one: it's just as if they had both been running and doing
the very same things from start - "as far as they know". *After* the
fork() takes place, things change. The very first thing that changes
is the return value of fork() itself. Apart that, you may have the
rest of the code do the same things for both processes, but that's not
very interesting, and generally you want to use the return value to
decide which is which and take actions accordingly.
Michele
--
{$_=pack'B8'x25,unpack'A8'x32,$a^=sub{po
p^pop}->(map substr
(($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^<R<Y]*YB='
..'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,$_,
256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,
| |
|
| Many thanks to all that posted on this one. I believe I'm pretty
clear on how this works and have enjoyed the varyious methods of
approaching this understanding. I say this not only to express
appreiation, but to ask what I hope is ONE LAST QUESTION on this
matter, but I have the sinking feeling that there is no such thing as
a final question, but I'm going to post it anyway.
Here's where I'm at: consider the code which was presented earlier in
the post:
unless ($pid = fork()) {
# Do something as a child process
exit;
}
# Do something as the parent process
on the execution of the fork, the statement '$pid = fork' evaluates as
true--I'm presuming from having run it--in the parent process (again,
assume success). In the spawned child process...and here's the big
leap for me...the statement '$pid = fork' does not execute (since
another process is not spawned) and the original fork() call merely
provides a false value to the child process at the fork's point of
execution--in this case it also provides a 0 to the child's
$pid variable. The provided false value to the child process allows
the condition of the 'unless' statement to evaluate false and
therefore execute the 'unless' block of code.
Have I finally achieved enlightenment? :)
| |
| Jürgen Exner 2007-02-22, 7:04 pm |
| Monty wrote:
> unless ($pid = fork()) {
> # Do something as a child process
> exit;
> }
> # Do something as the parent process
>
> on the execution of the fork, the statement '$pid = fork' evaluates as
> true--I'm presuming from having run it--in the parent process (again,
> assume success).
So far, so good.
> In the spawned child process...and here's the big
> leap for me...the statement '$pid = fork' does not execute
Wrong. You are correct, the fork() itself is executed only once (i.e. in the
parent process).
However the assignment $pid=[whatever] is the very first statement that is
executed in the child process, too.
Maybe you are as to the execution sequence. In an assignment
obviously you need to compute the value of the right-hand-side (RHS) first
before assigning the result to the a variable.
Therefore first the fork() is executed (only once), now all of a sudden you
got two individual processes, and in both processes the return value of
fork() is assigned to their respective $pid variable, and then both
processes continue execution.
jue
| |
| Michele Dondi 2007-02-22, 7:04 pm |
| On 22 Feb 2007 08:35:41 -0800, "Monty" <dale.schmitz@offutt.af.mil>
wrote:
>assume success). In the spawned child process...and here's the big
>leap for me...the statement '$pid = fork' does not execute (since
>another process is not spawned) and the original fork() call merely
It DOES execute! fork() is indeed a somewhat esoteric function: it
excutes in two different processes, one of which is created by itself.
It simply returns different values in each of them.
>Have I finally achieved enlightenment? :)
Sort of.
Michele
--
{$_=pack'B8'x25,unpack'A8'x32,$a^=sub{po
p^pop}->(map substr
(($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^<R<Y]*YB='
..'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,$_,
256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,
| |
|
| Let me rephrase my question...I don't think I'm asking something
correctly. Or, maybe I am and I'm just not understanding your answers.
My question probably has more to do with the evaluation of the true/
false condition in the 'unless' statement at this point. Assuming
$var = 1 is a successful assignment, then 'if ($var = 1)' would
evaluate as true (as would 'if ($var ==1)', but the point is that
there's an operation in the conditional test, and I'm thinking that
the success of that operation is what determines the truth/falseness
of the expression). If that's wrong, then correct me right here,
otherwise I'm assuming that the statement 'unless($pid = fork())' is
not evaluated on the value stored in $pid, but on whether or not the
operation of forking was successful. This is at the crux of my
understanding why the conditional test is true for the parent and
false for the child. It would be easier from a certain aspect if the
statement was 'unless($pid)', but that's not what's being done here.
| |
| anno4000@radom.zrz.tu-berlin.de 2007-02-22, 7:04 pm |
| Monty <dale.schmitz@offutt.af.mil> wrote in comp.lang.perl.misc:
> Let me rephrase my question...I don't think I'm asking something
> correctly. Or, maybe I am and I'm just not understanding your answers.
>
> My question probably has more to do with the evaluation of the true/
> false condition in the 'unless' statement at this point. Assuming
> $var = 1 is a successful assignment, then 'if ($var = 1)' would
> evaluate as true (as would 'if ($var ==1)', but the point is that
> there's an operation in the conditional test, and I'm thinking that
> the success of that operation is what determines the truth/falseness
> of the expression). If that's wrong, then correct me right here,
Well, it *is* wrong. To begin with, your terminology is off the
mark. 'if ($var = 1)' doesn't evaluate to anything, it isn't even
a statement. The complete "if ( ... ) { ... }" statement might
evaluate to something, but it doesn't either. Like loops, if has
no value.
That aside, the success of an operation doesn't necessarily determine
its value. Many system calls, like open(), mkdir(), and so on, do
that. fork(), however, and some others, behaves differently.
You have seen that on success fork() returns different values to
the parent and the child, the child's PID (true) to the parent and
0 (false, but a defined value) to the child. On failure, fork()
returns an undefined value (only to the parent, the child wasn't
created). That is how it is described in the pertinent perldoc,
and only that counts. Conclusions by analogy with "similar"
functions are misleading.
> otherwise I'm assuming that the statement 'unless($pid = fork())' is
> not evaluated on the value stored in $pid, but on whether or not the
> operation of forking was successful.
Again, no. I fail to see how this is a contrast to your first
assumption.
> This is at the crux of my
> understanding why the conditional test is true for the parent and
> false for the child. It would be easier from a certain aspect if the
> statement was 'unless($pid)', but that's not what's being done here.
The code
my $pid = fork();
unless ( $pid ) {
# child code
exit;
}
# and so on
would be exactly equivalent.
Anno
| |
|
| I see the error in my thinking. Somewhere along the lines, between
teaching myself Perl, C++, Tcl/Tk, Ada, and various flavors of shells,
I ran across a piece of knowledge that said executable statements
could be put in place of conditional tests and the truth/falseness
would be based on the success of that executable statement. I was
erroneous in thinking that Perl did this and that's behind my
confusion over the 'unless' statement. I found this out by running a
bit of test code:
'if ($pid = 0)' evaluates to false and 'if ($pid = 1)' evaluates to
true
'if ({$pid = 0})' evaluates to true, as does 'if ({$pid = 1})'
I assumed the second form of the if statement was Perl behavior.
That clears things up considerably.
I'm going to end this discussion right here. Thanks again to all!
| |
| Uri Guttman 2007-02-22, 7:04 pm |
| >>>>> "M" == Monty <dale.schmitz@offutt.af.mil> writes:
M> 'if ($pid = 0)' evaluates to false and 'if ($pid = 1)' evaluates to
M> true
M> 'if ({$pid = 0})' evaluates to true, as does 'if ({$pid = 1})'
why are the {} in there? those are anon hashes which you don't want
(they will always be true and warnings will point out the odd number of
initializers). where did you get the idea that {} is needed there?
M> I assumed the second form of the if statement was Perl behavior.
huh?
perl has a very simple rule about expressions. all expressions have a
value. simple. that value can be used in many ways and contexts. if()
provides a boolean (which is also scalar) context on the expression
inside (). that is ALL that happens. never assume from other langs what
perl does. perl likely does what you want and in a simpler way.
M> That clears things up considerably.
not for me. you still seem to not understand perl's expressions. fork
is just a function that returns a value so it is an expression. but it
happens to have the most powerful side effect of any perl call as it
creates a new copy of that process for you. and it is not a perl thing
but an OS thing that perl supports directly.
uri
--
Uri Guttman ------ uri@stemsystems.com -------- http://www.stemsystems.com
--Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
| |
| Jürgen Exner 2007-02-22, 7:04 pm |
| Monty wrote:
> Let me rephrase my question...I don't think I'm asking something
> correctly. Or, maybe I am and I'm just not understanding your answers.
>
> My question probably has more to do with the evaluation of the true/
> false condition in the 'unless' statement at this point. Assuming
> $var = 1 is a successful assignment, then 'if ($var = 1)' would
> evaluate as true (as would 'if ($var ==1)', but the point is that
> there's an operation in the conditional test,
Well, right. I assume with operation you mean the assignment?
> and I'm thinking that
> the success of that operation is what determines the truth/falseness
> of the expression).
Wrong.
> If that's wrong, then correct me right here,
The operation has a return value. For some operations that return value may
indicate success or failure. For others like e.g. + or = or s/// or many,
many others the return value indicates something totally different.
The assignment operator return the value it was assigning to the variable.
Unfortunately that is not clearly spelled out in perldoc perlop.
jue
> otherwise I'm assuming that the statement 'unless($pid = fork())' is
> not evaluated on the value stored in $pid, but on whether or not the
> operation of forking was successful.
Neither nor. The conditional is evaluated on the return value of the
assignment, which happens to be the return value of fork(), which happens to
be different for parent and child.
For the sake of the conditional your code is equivalent to
unless (fork()) {
# child code
exit;
}
The only reason for the explicit assignment of the return value of fork() to
a variable is that later on the parent process can use that PID to identify
its own children by their process IDs.
jue
| |
| Michele Dondi 2007-02-22, 7:04 pm |
| On 22 Feb 2007 11:30:00 -0800, "Monty" <dale.schmitz@offutt.af.mil>
wrote:
>Let me rephrase my question...I don't think I'm asking something
>correctly. Or, maybe I am and I'm just not understanding your answers.
Please quote some context when replying. Otherwise it's hard to
understand what you're referring to.
>My question probably has more to do with the evaluation of the true/
>false condition in the 'unless' statement at this point. Assuming
Make it an C<if> if that's easier for you to understand.
>$var = 1 is a successful assignment, then 'if ($var = 1)' would
There's no concept of a "successful assignment", for an assignment in
some sense cannot fail. It's an expression, though, which returns a
value, which in turn happens to be what's on the rhs. If the rhs is
true, then so is the assignment.
>evaluate as true (as would 'if ($var ==1)', but the point is that
This is not true: C<$var ==1> may evaluate as false.
>there's an operation in the conditional test, and I'm thinking that
>the success of that operation is what determines the truth/falseness
>of the expression). If that's wrong, then correct me right here,
Yes, of course!
>otherwise I'm assuming that the statement 'unless($pid = fork())' is
>not evaluated on the value stored in $pid, but on whether or not the
>operation of forking was successful. This is at the crux of my
But the two correspond, as $pid is populated with the return value
from fork().
>understanding why the conditional test is true for the parent and
>false for the child. It would be easier from a certain aspect if the
>statement was 'unless($pid)', but that's not what's being done here.
If it's easier for you to understand you can do
my $pid=fork;
unless ($pid) { # whatever
just as finely.
Michele
--
{$_=pack'B8'x25,unpack'A8'x32,$a^=sub{po
p^pop}->(map substr
(($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^<R<Y]*YB='
..'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,$_,
256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,
| |
| Michele Dondi 2007-02-22, 7:04 pm |
| On 22 Feb 2007 13:29:54 -0800, "Monty" <dale.schmitz@offutt.af.mil>
wrote:
>I see the error in my thinking. Somewhere along the lines, between
For the second time in a row: please quote some context!
>teaching myself Perl, C++, Tcl/Tk, Ada, and various flavors of shells,
>I ran across a piece of knowledge that said executable statements
>could be put in place of conditional tests and the truth/falseness
>would be based on the success of that executable statement. I was
>erroneous in thinking that Perl did this and that's behind my
>confusion over the 'unless' statement. I found this out by running a
>bit of test code:
I can't remember C/C++ to be affected by what that you describe. I
hardly can imagine an assignment to "fail" either. Well, overloading
and "esoteric" variables (i.e. tied ones in Perl).
>'if ({$pid = 0})' evaluates to true, as does 'if ({$pid = 1})'
Do you have the slightest idea of what you're doing here? Indeed they
both "evaluate to" true: it's just as if you wrote
my %hash=(foo => 1, bar => 2);
if (\%hash) { # ...
All references are true!
>I assumed the second form of the if statement was Perl behavior.
Huh?!?
>That clears things up considerably.
I doubt that.
Michele
--
{$_=pack'B8'x25,unpack'A8'x32,$a^=sub{po
p^pop}->(map substr
(($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^<R<Y]*YB='
..'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,$_,
256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,
| |
| Tad McClellan 2007-02-22, 7:05 pm |
| Monty <dale.schmitz@offutt.af.mil> wrote:
> I see the error in my thinking. Somewhere along the lines, between
> teaching myself Perl, C++, Tcl/Tk, Ada, and various flavors of shells,
> I ran across a piece of knowledge that said executable statements
> could be put in place of conditional tests and the truth/falseness
> would be based on the success of that executable statement. I was
> erroneous in thinking that Perl did this and that's behind my
> confusion over the 'unless' statement. I found this out by running a
> bit of test code:
>
> 'if ($pid = 0)' evaluates to false and 'if ($pid = 1)' evaluates to
> true
No, no, no. Rather:
'if ($pid = 0)' does not execute its block, and 'if ($pid = 1)'
does execute its block.
(an if statement does not "evaluate" to anything, because it
is not an expression.)
or
'$pid = 0' evaluates to false and '$pid = 1 evaluates to true
(because assignment in scalar context evaluates to whatever is
on the RHS of the assignment.)
> 'if ({$pid = 0})' evaluates to true, as does 'if ({$pid = 1})'
The curlys return a reference to a hash, and references
are always a true value.
> That clears things up considerably.
But it doesn't.
> I'm going to end this discussion right here.
Don't stop yet, unless you got the part of Uri's and Michele's
posts about the value of an assignment statement in scalar context.
--
Tad McClellan SGML consulting
tadmc@augustmail.com Perl programming
Fort Worth, Texas
| |
| Kevin Michael Vail 2007-02-23, 4:06 am |
| In article <8OjDh.1958$aM.1775@trndny03>,
"Jürgen Exner" <jurgenex@hotmail.com> wrote:
> Therefore first the fork() is executed (only once), now all of a sudden you
> got two individual processes, and in both processes the return value of
> fork() is assigned to their respective $pid variable, and then both
> processes continue execution.
The way it was explained to me way back when I was learning Unix was
that fork() is called once, but returns twice, once in each process (and
then I found out that exec() is called once, and doesn't return at all,
so there is balance in the world).
--
Kevin Michael Vail_ | "This is so I have to go to the bathroom!"
kevin@vaildc.net_ _ | _ _ _ _ _ _ _ _ _ -- Calvin
| |
|
| It would appear that I may have stepped on toes with my process of
learning here. I had a particular goal in mind when I first posted
this question and unfortunately, that goal wasn't clear until it was
achieved: 1) a working understanding of what fork() does, and 2)
clarification regarding the evaluation of assignment statements in a
conditional context. Even though that second one may not be complete,
I have a functional understanding, thanks entirely to this group, of
the particulars, pitfalls, and benefits.
I probably committed a breech of protocol by not posting snippets of
discussion that led me to conclusions that I, in turn, posted. My
apologies, but what I've learned has been gleaned over the course of
discussion by osmosis and 'nuance' that I got from the discussion, and
I felt that my focus on the goal would not have been served, in fact
debilitated, by detailed examination of my path though all of this.
I've accomplished what I wanted here, and even if I didn't learn
exactly what you were trying to teach me, I learned enough to write my
own tests for aspects I was unclear on, and I have a better, more
functional knowledge of what's going on.
So please accept my thanks graciously. I realize my knowledge is
incomplete, but for this task, it's what I need to know. And without
the help of this group, I never would have gotten there.
| |
| A. Sinan Unur 2007-02-23, 7:07 pm |
| "Monty" <dale.schmitz@offutt.af.mil> wrote in news:1172179794.802618.104920
@v45g2000cwv.googlegroups.com:
> I'm going to end this discussion right here. Thanks again to all!
On the UseNet, you don't get to decide when the discussion ends.
Sinan
| |
|
| Take it for how it was meant.
|
|
|
|
|