进程ID
- 进程==程序的运行实例
- 程序+程序加载器(内核)⇒进程
- 每个进程都有进程ID(PID)
- pid_t:唯一标识进程的正整数
- getpid()返回调用者的PID
- 内核使用“电梯”算法分配PID
- 当电梯到达范围上限时,它循环使用
- PID从范围低端重新开始
- Linux系统最大PID为32767
- 若所有PID槽位已用⇒fork()调用失败并返回EAGAIN
- 上限可通过/proc/sys/kernel/pid_max调整(上限为
- 内核PID_MAX_LIMIT常量,通常为4×1024×1024)
父进程
#include <unistd.h>
pid_t getppid(void);
- 每个进程都有父进程
- 通常,使用fork()创建该进程的进程即为父进程
- 子进程终止时会通知父进程
- 系统中所有进程由此形成树状结构
- 根节点为init进程(PID=1),乃所有进程的始祖
- “孤儿”进程将被init进程“收养”
- getppid()返回调用者父进程的PID(PPID)
进程内存布局
readelf - 查看ELF文件的内存布局
进程的虚拟内存划分为段:
- 文本段:机器语言指令(可执行代码)
- 标记为只读以防止自我修改
- 多个进程可在内存中共享相同代码
- 在ELF文件中对应
.text节
- 初始化数据:显式初始化的全局变量和静态变量
- 进程创建时从程序文件读取值
- 未初始化数据:未显式初始化的全局及静态变量
- 进程创建时初始化为零
- 栈:用于存储函数局部变量及调用链路信息(保存的栈指针SP和程序计数器PC寄存器)
- 默认大小:通常8MB(可通过
ulimit -s调整)
- 默认大小:通常8MB(可通过
- 堆:可动态分配与释放内存的区域
- malloc()与free()函数
高地址 0xFFFFFFFF
+----------------------+
| 内核空间 | 1GB (用户进程不可直接访问)
| (Kernel Space) |
+----------------------+ 0xC0000000
| |
| 栈 | (向下增长)
| (Stack) |
| |
+----------------------+
| ↓ |
| |
| ↑ |
+----------------------+
| 内存映射区 | (共享库、文件映射等)
| (Memory Mapping) |
+----------------------+
| |
| 堆 | (向上增长)
| (Heap) |
| |
+----------------------+
| BSS 段 | (未初始化静态/全局变量)
| (.bss) |
+----------------------+
| 数据段 | (已初始化静态/全局变量)
| (.data) |
+----------------------+
| 代码段 | (程序指令,只读)
| (.text) |
+----------------------+ 0x08048000 (32位典型起始)
低地址 0x00000000
环境变量列表
# 查看当前shell的环境变量
cat /proc/PID/environ | tr '\0' '\n'
/proc文件系统
/proc 是 Linux 系统中的一个 虚拟文件系统,它不占用实际的磁盘空间,而是由内核在内存中动态生成,提供了访问内核内部数据结构和进程信息的接口。
进程
进程信息:
/proc/1234/
├── cmdline # 启动进程的完整命令行(以\0分隔)
├── comm # 进程的命令名(可修改,不超过16字符)
├── cwd -> /path # 符号链接到进程当前工作目录
├── environ # 进程的环境变量(\0分隔)
├── exe -> /bin/bash # 符号链接到可执行文件
├── fd/ # 打开的文件描述符
│ ├── 0 -> /dev/pts/1 # stdin
│ ├── 1 -> /dev/pts/1 # stdout
│ └── 2 -> /dev/pts/1 # stderr
├── fdinfo/ # 文件描述符详细信息
├── maps # 进程内存映射(地址空间布局)
├── mem # 进程内存(需通过工具访问)
├── mountinfo # 进程相关的挂载信息
├── mounts # 进程挂载的文件系统
├── net/ # 进程的网络信息
├── ns/ # 进程的命名空间
├── pagemap # 页表映射信息
├── root -> / # 符号链接到进程根目录
├── smaps # 详细的内存映射统计
├── stat # 进程状态信息(单行,空格分隔)
├── statm # 内存状态(单行,页为单位)
├── status # 进程状态(可读格式)
└── task/ # 线程信息(每个线程一个子目录)
└── [TID]/ # 线程ID目录,结构与进程类似
系统信息:
/proc/
├── cpuinfo # CPU详细信息(型号、核心、频率)
├── meminfo # 内存使用统计(物理内存、交换空间)
├── loadavg # 系统负载(1、5、15分钟平均负载)
├── uptime # 系统运行时间(秒)
├── version # 内核版本和编译信息
├── filesystems # 支持的文件系统列表
├── interrupts # 中断统计
├── iomem # 物理内存映射
├── ioports # I/O端口范围
├── mounts # 已挂载的文件系统
├── net/ # 网络协议统计和配置
│ ├── tcp # TCP套接字状态
│ ├── udp # UDP套接字状态
│ ├── arp # ARP表
│ └── route # 路由表
├── scsi/ # SCSI设备信息
├── sys/ # 可调整的内核参数(见下文)
├── tty/ # 终端信息
└── ... # 其他很多文件