这是一段代码:
int i=0;
pid_t pid;
puts("Hello, World!");
puts("");
pid = fork();
if(pid)
i=42;
printf("%p\n", &i);
printf("%d\n", i);
puts("");
输出
Hello, World!
0x7fffc2490278
42
0x7fffc2490278
0
程序打印Hello,World!有一次,所以孩子的过程从一开始就没有开始,也没有重新定义变量。变量的地址是相同的。所以他们是一样的。但是我改变了父进程中的值,它首先被执行,它对于子进程没有改变。为什么呢?
答案 0 :(得分:10)
变量的地址是相同的。所以他们是一样的。但是我在父进程中更改了i的值,它首先被执行,它对于子进程没有改变。为什么呢?
地址属于流程范围。它们是虚拟地址。父进程中的地址0x7fffc2490278
和子进程中的0x7fffc2490278
是不同的物理地址。
答案 1 :(得分:4)
执行fork()
时,将创建包含变量的整个过程。因此,父级中的i
不是孩子的i
。它们具有相同的虚拟地址,但物理地址不同。修改完全独立。
答案 2 :(得分:3)
来自man page for fork:
成功时,子进程的PID在父进程中返回, 在孩子身上返回0。失败时,返回-1 parent,没有创建子进程,并且正确设置了errno。
也就是说,因为父pid被设置为大于0的数字(如果你也应该检查失败,则为-1)。
if(pid)
评估为if(true)
它将为父母执行。然而,孩子被分配到pid
(他们知道孩子是怎么回事)。
if(0)
评估为if(false)
因此i的值不会改变。
但是,由于抽象,该过程会在虚拟地址(虚拟地址空间完全复制fork
)中看到内存。只有内核可以管理物理地址,并且进程与内核通信以获取此内存(该过程只是说"将此变量i
放在此地址:0x7fffc2490278
" 并且内核基本上将它映射到任何想要的地方)。就流程所知,它是唯一一个要求记忆的过程,这就是为什么他们的地址是相同的"。
答案 3 :(得分:2)
变量存在于进程的虚拟地址空间中。进程的地址空间是该进程的本地空间。您在两次处理中看到相同地址这一事实并不意味着您正在访问同一个变量。完全没有。
地址值仅在其自身流程的上下文中才有意义。比较不同流程的地址是没有意义的。地址空间。
父进程中的变量i
与子进程中的变量i
完全分开。您只更改了一个i
(父级'),这正是您在输出中观察到的内容。