1
$\begingroup$

I am studying operating systems and was going through Copy On Write mechanism. From Wiki:

When one process modifies the memory, the operating system's kernel intercepts the operation and copies the memory; thus a change in the memory of one process is not visible in another's.

It says a particular virtual page is remapped if any of the processes that are sharing the address space tries to modify any data value. So, I tried testing it by writing following code :

#include<stdio.h>
#include<stdlib.h>

int main()
{
        pid_t pid;
        int a = 30;
        pid = fork();

        if(pid == 0)
        {
                printf("Parent\t %x\t %d\n",&a,a);
        }
        else
        {
                printf("Child\t %x\t %d\n",&a,a);
                a = 25;
                printf("Child\t %x\t %d\n",&a,a);
        }

        return 0;
}

Now when I run the program, the output I get is :

$ ./test 
Child    ae9dfe3c        30
Child    ae9dfe3c        25
Parent   ae9dfe3c        30

I understand why the address in first and third line are same but my doubt is why is the memory location in second line same as the other two? It should be different because the child process is modifying the value of a ?

$\endgroup$
5
  • 1
    $\begingroup$ That's a virtual address. $\endgroup$
    – BartoszKP
    Commented May 11, 2016 at 9:41
  • $\begingroup$ @BartoszKP I understand that. My doubt is why all the three are same? The address in second line should be different from others, because the data value has been modified, right? $\endgroup$
    – Mojo Jojo
    Commented May 11, 2016 at 12:32
  • $\begingroup$ @MojoJojo It shouldn't be different, because the whole mechanism should be transparent. What changes is the physical address, virtual remains the same. I can't even imagine headaches programmers would have if they would need to take into account possibility that addresses of their variables will fluctuate as the program executes. $\endgroup$
    – BartoszKP
    Commented May 11, 2016 at 13:15
  • $\begingroup$ @BartoszKP Ok, So when child process modifies the data value, the corespond particular physical page is re-built but its still mapped to same virtual address. Thanks. $\endgroup$
    – Mojo Jojo
    Commented May 11, 2016 at 13:19
  • $\begingroup$ @MojoJojo That's only my educated guess :) But the accepted answer seems to confirm this. Cheers! $\endgroup$
    – BartoszKP
    Commented May 11, 2016 at 13:34

1 Answer 1

4
$\begingroup$

The fork primitive makes a copy of the process. From within the processes, the parent and the child are almost identical; the few differences are the return value of the fork primitive and a few characteristics such as the process ID.

Copy-on-write is an implementation optimization. It isn't visible from inside the process. You'd need to look inside the kernel to see it, or use some reporting tools that expose this information. For example, you can observe it indirectly through memory usage statistics.

What you're printing out are the virtual addresses of the variables. They're the same: that's the whole point of fork — it creates a (near-)identical copy of the process.

Under the hood, when the child modifies the value of a, the kernel makes a copy of the page that contains it. Before that point, the variable a in the parent process and in the child process are stored in the same memory. After that point, they are stored in different memory: the parent and the child now each have their own page. But the two processes map their respective pages at the same address — the address of a variable doesn't change (it can't change, because that's how the code locates the variable).

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.