为什么fork()使用相同的变量但不同的值
Why fork() use the same variable but different value?
代码:
#include <stdio.h>
#include <unistd.h>
void f(int&);
void g(int&);
int main(int argc, char **argv)
{
printf("--beginning of programn");
int counter = 0;
pid_t pid = fork();
if (pid == 0) {
f(counter);
printf("child process: %d, %p", counter, &counter);
} else if (pid>0) {
g(counter);
for (int i=0; i<5; ++i) {
sleep(1);
printf("parent process: %d, %pn", counter, &counter);
}
}
printf("--end of program--n");
return 0;
}
void f(int& counter) {
counter = 1;
printf("in f: %d, %p-n", counter, &counter);
}
void g(int& counter){
}
,结果如下:
--beginning of program
in f: 1, 0x7ffc9b01c6a4-
child process: 1, 0x7ffc9b01c6a4--end of program--
parent process: 0, 0x7ffc9b01c6a4
parent process: 0, 0x7ffc9b01c6a4
parent process: 0, 0x7ffc9b01c6a4
parent process: 0, 0x7ffc9b01c6a4
parent process: 0, 0x7ffc9b01c6a4
--end of program--
显然在子进程中是相同的参数,地址相同,但值不同。
为什么会这样?
每个进程都有自己的虚拟内存空间
这意味着一个进程中的0x7ffc9b01c6a4
与另一个进程中的0x7ffc9b01c6a4
完全无关。
这不是同一个对象;它是新工艺中的一个对象。由于第二个进程是从第一个进程派生出来的,本质上是克隆了这个进程,所以对象在第二个进程中应该存在于与第一个进程相同的虚拟内存位置也就不足为奇了。
这是fork()
的基础,这正是允许它工作的原因。要理解这一点,您需要记住,在现代操作系统中,进程的所有地址空间都是虚拟的——这意味着,它与实际的物理内存地址无关。访问地址0x8000的内存(如果我没记错的话)直接访问视频内存的日子已经一去不复返了。我曾经用这种方式编程,而不是屏幕操作例程只是在显存中写入值,这要快得多。这是有趣的:)
但它不再是。现在在用户程序中,地址与物理内存无关,每当您访问位于位置'0x1234567'的内存时,都会进行转换。CPU知道如何将这个虚拟地址映射到物理内存地址,但是没有其他人知道。
因此,当您fork进程时,会生成一个精确的内存副本。它具有相同的虚拟地址(因为内存副本是精确的!)。但是由于现在是一个不同的进程,CPU会将这些虚拟地址转换为不同的物理内存地址。至少,这是语义。在真正的现代系统中,确切的内存副本不会真正发生—或者fork()
需要很长时间。相反,内存被标记为"写时复制"。这意味着在数据被修改之前,两个进程将访问相同的物理内存。但是一旦任何进程修改了内存,它就会被复制,现在每个进程都有自己的副本。
相关文章:
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 将数组的地址分配给变量并删除
- 为"adjacent"变量赋值时出现问题
- enum是C++中的宏变量还是整数变量
- 在全局变量中保存类的实例以重新创建类(创建"backup")
- 用C++中的一个变量定义一个常量
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 你能重载对象变量名本身返回的内容吗
- 内置函数可查看CPP中的成员变量
- 是否可以初始化不可复制类型的成员变量(或基类)
- 尝试通过多个向量访问变量时,向量下标超出范围
- 试图让变量检查数组中的某些内容
- Cpp-Tuple使用带有变量的get
- 将包含C样式数组的对象初始化为成员变量(C++)
- 当vector是tje全局变量时,c++中vector的内存管理
- 通过多个头文件使用常量变量
- std::threads可以从Windows DLL中的全局变量创建/销毁吗?
- 执行函数时导致崩溃的变量
- 为什么fork()使用相同的变量但不同的值