Linux Process Address Space

  high address   +---------------+
                 |               |
                 |     Stack     |    int local_b
                 |               |
                 +---------------+
                 |       |       |
                 |       v       |
                 |               |
                 |               |
                 |       ^       |
                 |       |       |
                 +---------------+
                 |               |
                 |     Heap      |    int * heap_c = malloc()
                 |               |
                 +---------------+
                 |     Data      |    int global_a
                 +---------------+
                 |     Code      |
  low address    +---------------+

上图是 Linux 的进程地址空间,从低位到高位地址分别为:

  • Code Segment: 程序的代码,CPU 执行的指令部分,共享只读
  • Data Segment: 可细分为初始化数据段和未初始化数据段,常用于存储全局变量等
  • Stack: 函数以及自动变量(未加 static 的自动变量又称为局部变量)
  • Heap: 动态分配内存,如 malloc() 分配的内存

更为详细的介绍请见 Anatomy of a Program in Memory


Fork

                  Parent Process             Child Process

  high address   +---------------+          +---------------+
                 |               |          |               |
                 |     Stack     |          |     Stack     |
                 |               |          |               |
                 +---------------+          +---------------+
                 |       |       |          |       |       |
                 |       v       |          |       v       |
                 |               |          |               |
                 |               |          |               |
                 |       ^       |          |       ^       |
                 |       |       |          |       |       |
                 +---------------+          +---------------+
                 |               |          |               |
                 |     Heap      |          |     Heap      |
                 |               |          |               |
                 +---------------+          +---------------+
                 |     Data      |          |     Data      |
                 +---------------+----------+---------------+
                 |                   Code                   |
  low address    +------------------------------------------+

fork 是 linux 中最重要的系统调用之一,用于创建一个新进程,它完全的复制父进程地址空间的 data segment、 heap 和 stack,但是和父进程共享一个 code segment,因为 code segment 通常为只读,从逻辑的角度来看,子进程和父进程的内存地址空间互相独立,子进程修改自己的 data segment,heap 和 stack 并不影响父进程内存空间。每次调用 fork,返回两次结果,其中父进程的返回值为子进程的 pid,子进程的返回值为 0。

#include<stdio.h>