in reply to Keeping variables throug a fork

Because after the fork there's two different processes with two different copies of $a. The child modifies its $a, but the parent's copy is unmodified. You'd either need to use threads (which have their own headaches) or something like IPC::Shareable to make a single variable visible in multiple execution contexts.

Replies are listed 'Best First'.
Re^2: Keeping variables throug a fork
by Anonymous Monk on Jul 06, 2007 at 01:27 UTC
    I'm confused: I thought references were supposed to be pointers to locations in memory. How could memory split from a fork?
      How could memory split from a fork?

      On a modern Unix-like memory system, fork() creates a new process within the kernel. The process has its own ID and its own scheduling. That's why multiple processes can execute more-or-less simultaneously.

      Each process also has its own memory space. However, a fork()ed process begins execution from the point of the fork() call. Thus it needs to have a copy of the parent process's memory space. (It needs a copy so that they can have separate memory spaces, otherwise every process would have the potential to write into any other process's memory space, which would be bad for system stability.)

      Because copying megabytes and potentially gigabytes of memory from one page into another every time you call fork() would be very expensive, modern Unix-like kernels use a copy-on-write scheme. Instead of copying the memory pages in a fork()ed child, the kernel copies only the page tables for the process. Think of this as a list of memory pages the process used. It also sets a special flag on each page table entry so that when anything writes to one of the pages, the kernel does the copy then, and writes the modifications to the copied entry.

      This is very efficient for several reasons.

      Because your code modifies a variable in the child process, whatever page of memory (or pages) used to store those values immediately get copied and go unshared. The parent process keeps the current page with the current values and the child process gets a new page with the new values.

      (I realize as I write this that I don't know exactly how the kernel handles the situation where the parent process modifies a page shared with one or many children, but I'm pretty sure there's a copy there too.)

        Works great in C code where read accesses to variables doesn't change anything.

        In perl, where a read access can cause change: like using a string scalar (PV) in a numeric context; or an integer or real scalar (IV or NV) in a string context; or taking a reference to any type of variable; or an other operation that causes the SVs contents to change as a result of a Perl level read access; and the 4k page that SV lives in, has to be copied.

        Still beneficial, but not always as beneficial as it at first might appear.


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.

      Erm, because that's what it does. On most modern OSen (that I'm familiar with) separate processes get their own distinct address space that is distinct from all other processes executing on the same machine (unless you use some mechanism such as the aforementioned shared memory to arrange otherwise). Threads are multiple threads of execution in the same process' execution context and hence share the same address space. Perhaps you're confuzzled between processes and threads . . .