10.程序地址空间_1
程序地址空间概念的引出
请先思考以下部分代码
程序代码
1 #include <stdio.h>2 #include <unistd.h>3 #include <stdlib.h>4 #include <sys/types.h>5 6 int g_val = 0;7 8 int main()9 {10 pid_t id = fork();11 if(id < 0)12 {13 perror("fork");14 return 0;15 }16 else if(id == 0)17 { //child18 int cnt = 0;19 while(cnt <= 10)20 {21 printf("child[%d]: %d : %p\n", getpid(), g_val, &g_val);22 sleep(1);23 cnt++;24 if(cnt == 10)25 {26 g_val = 100; 27 printf("子进程已经更改全局变量了...... ");28 }29 }30 }31 else32 { //parent33 while(1)34 {35 36 printf("parent[%d]: %d : %p\n", getpid(), g_val, &g_val);37 sleep(2);38 }39 }40 return 0;41 }
程序输出结果
我们可以发现此时全局变量的值已经被修改了,但是同样地址的情况下,其中的数据内容竟然是不一样的
- 父子进程中
&g_val
的地址是一样的 - 但它们的值是独立的
✅ 为什么地址一样但值不共享?
因为 fork()
会复制整个进程的地址空间,包括代码段、数据段、堆和栈。虽然地址一样,但父子进程拥有各自独立的内存副本。
这叫做:
写时复制(Copy-On-Write)机制
当子进程修改 g_val
时,系统会为它分配新的物理内存,父进程的 g_val
不会被影响。
📌 关键知识点总结
知识点 | 说明 |
---|---|
fork() | 创建一个新进程,返回两次:子进程返回 0,父进程返回子进程 PID |
pid_t | 是进程 ID 的类型,定义在 <sys/types.h> |
全局变量复制 | 父子进程各自拥有独立的 g_val 副本 |
地址空间复制 | 虽然地址一样,但物理内存不同 |
写时复制机制 | 修改时才真正分配新内存,节省资源 |
getpid() | 获取当前进程的 PID,用于区分父子进程 |
sleep() | 控制输出节奏,便于观察变化 |