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

I've this code:
#!/usr/bin/perl -w use strict; my $testVar = 1; my $ptr = \$testVar; if (my $pid = fork) { while (1) { print "from parent: $testVar \n"; print "ptr from parent: $ptr \n"; sleep 2; } waitpid($pid, 0); } else { while (1) { print "from child: $testVar \n"; print "ptr from client: $ptr \n"; $$ptr++; sleep 2; } exit; }
which prints this:
from child: 1 ptr from client: SCALAR(0x814db78) from parent: 1 ptr from parent: SCALAR(0x814db78) from child: 2 ptr from client: SCALAR(0x814db78) from parent: 1 ptr from parent: SCALAR(0x814db78) from child: 3 ptr from client: SCALAR(0x814db78) from parent: 1 ptr from parent: SCALAR(0x814db78) from child: 4 ptr from client: SCALAR(0x814db78) from parent: 1 ptr from parent: SCALAR(0x814db78)
Now, I expected the parent to see the newly incremented value of $testVar but I don't. Why is that? Doesn't the reference point to a location in memory that is shared by both the parent & the child?

Replies are listed 'Best First'.
Re: trying to understand references
by ikegami (Patriarch) on Dec 21, 2005 at 19:19 UTC

    Welcome to the world of paged virtual memory, where every process has its own memory space.

    It is virtual, because memory address 0x814db78 in process A is different from memory address 0x814db78 in process B.

    Where 0x814db78 is actually located in memory can change at any time. It could even be swapped out to disk. Paging allows this.

    Therefore, just because Perl prints 0x814db78 for both variables doesn't mean it's the same variable.

     

    It is possible to share memory between processes on some platforms. I believe there is a module to do just that in the IPC hierarchy.

    Update: IPC::Shareable looks promising.

Re: trying to understand references
by BrowserUk (Patriarch) on Dec 21, 2005 at 19:24 UTC
    I expected the parent to see the newly incremented value of $testVar but I don't. Why is that?

    Because forked processes do not share memory. Or rather, they do not have write access to shared memory.

    On systems supporting COW, child and parent will share read access to the memory, but at the point that the child attempts to modify that shared memory, it will be duplicated and then the child's copy will be modified leaving the parents's copy as it was at the fork point. That is, the memory is Copied On Write (COW).

    On systems not supporting COW, parent and child will each get their own copy at the fork point.

    Slightly complicating the picture is the fork emulation on Win32, which is different again.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: trying to understand references
by tirwhan (Abbot) on Dec 21, 2005 at 19:26 UTC

    This has less to do with references than with processes. fork creates a new process with its own memory space, which is not shared between child and parent. The memory map that each process sees is the same (because the fork is an identical copy), but that's just the memory map of the process and it's not the same as the OSes virtual (or the machines physical) memory. You can use threads if you want to use shared memory, or explicitly set up a shared memory space (for example with IPC::ShareLite) for forked processes.


    Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it. -- Brian W. Kernighan