简体   繁体   中英

Fork - same memory addresses?

This is about C in Linux.

I have fork() in main() where I create 2 child processes. Then, in both child process a run the function abc() , where there is a local variable x . I write some value in it. Then I print the address of this variable with printf("%p",&x) .

Both processes print SAME address. I thought every child gets a (independent) copy of parent's memory. I need every process to have its own variable x . How can I do that or am I doing something wrong?

You need to understand that there is a disconnect between physical memory and the virtual address space of a process.

Every single process gets its own 4G virtual address space and it's the job of the operating systems and hardware memory managers to map your virtual addresses to physical ones.

So, while it may seem that two processes have the same address for a variable, that's only the virtual address.

The memory manager will map that to a totally different physical address a .

This mapping is also what allows you to run ten processes, each taking up 1G, even though your machine only has 4G of physical memory. The OS can swap bits of your memory out to disk and bring them back in when you try to use them.


a : Mostly, this is true. It may map to the same physical address if you're sharing stuff between processes. For example, shared memory, kernel code and data, dynamic libraries and so forth.

If you stop to think for a minute, it would be impossible for fork to give variables separate addresses in the parent and child process. You could already have stored the addresses anywhere in memory, or hashed them, or saved them out to a file, or anything, and then anything in the child that depended on these addresses being valid would horribly break. In fact fork does and must create a child process in which the virtual address space is identical to the virtual address space of the parent.

Because of the virtual memory system, each child processes have its own variable with the same (virtual) address.

The same virtual addresses won't point to the same physical location.

To understand how this can happen you need to understand process/thread model of Linux. Linux follows fork-and-exec model inherited from UNIX. Process spawned by fork() system call in this model is a something of a cross between thread and Windows process.

When the thread is spawned (doesn't matter in Linux or in Windows), new thread shares its address space with parent. Both can find the same objects by accessing to the same addresses. But these threads use different stacks. As a result local variables of both threads is guaranteed to be not have the same addresses.

When process is spawned in Windows environment, the OS build entirely new address space from the scratch and populate it by memory and data needed. In theory, local variable of both processes can have the same addresses but in practice probability of this will be very low. And even in the case when both variables will use the same address, these two variables will still be different objects.

Processes of UNIX have similarity with threads and with Windows processes. Like in the case of second one, OS will create NEW address space for a child process, but in contrast to Windows, Linux creates it by lazy copying of the parent process address space with use of Copy-On-Write (COW) approach. COW mean that both processes will share the same memory, but until the moment when one of them will modify it. On the moment of attempt to write to memory the OS will be involved again to make to copy chunk of memory which will be changed and assign one copy to parent and another one to child. Starting from this moment each process will work with its own independent copy of the objects in the modified chunk of memory, but they will still have the same addresses. The same is true for stack and local variables stored on it.

In your case you have two child with two copies of the same stack on which local variables are stored on the same addresses but in different address spaces. Then you have run the same code on both childs. In other words you have the same initial state of the stack layout and run the same code which modifies this layout in the same way. As a result you will have the same local variables located on the same addresses.

since you are printing the address of stack variable(local variable). its address will be same(does't matter you update its value or not). since both the process share a common virtual stack.

but if you are trying to print the address of a global variable inside common function(called from parent and child process) then its address will be same till the point you don't update it value. if a process update the value of global variable then that process will have unique copy of it(through copy on write mechanism).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM