Linux 进程与内存布局详解
1. 什么是进程
1.正在运行的程序,其运行过程中需要消耗内存和CPU。
gcc
main.c ---------->a.out ----------------->./a.out
应用程序 可执行程序 内存
硬盘 硬盘 cpu
程序和进程有什么区别?
程序:静态的数据集合,存储在硬盘空间
程序运行起来可以产生进程;
一个程序可以产生多个进程
进程:是一个程序动态执行的过程,需要消耗内存和CPU,
进程具备动态生命周期,从产生到调度再到消亡
一个进程中也可执行多个程序
项目 | 程序 | 进程 |
---|---|---|
存在形式 | 硬盘上的静态文件 | 内存中的动态执行单元 |
生命周期 | 长期存在 | 从创建到结束 |
数量 | 一个程序可运行多次 | 每次运行都是一个独立进程 |
2. Linux 进程内存布局
当一个进程被创建时,操作系统会为其分配 0~4GB 的虚拟内存空间(32 位系统)。这块虚拟地址空间通常被划分为以下几个区域:
1.1 文本区(Text Segment)
存放程序的可执行指令代码。
包含程序的常量(如字符常量 'A'
、数字常量 10
、0xAA
等)。
只读,防止程序意外修改指令。
生命周期:程序运行期间固定不变。
1.2 数据段(Data Segment)
分为两部分:
data 段:已初始化的全局变量、已初始化的静态变量。
bss 段:未初始化的全局变量、未初始化的静态变量(系统在程序启动时会将其置 0)。
1.3 字符串常量区
存放 C 语言中的字符串常量,例如 "hello world"
。
属于只读数据区的一部分。
1.4 堆区(Heap)
由程序员手动申请(malloc
、new
)。
生命周期由程序控制(free
、delete
)。
容量可以在运行时动态扩展或收缩。
1.5 栈区(Stack)
保存局部变量、函数参数和返回值。
保存函数的调用关系(保护现场、恢复现场)。
由系统自动分配和回收。
1.6 内核区
存放内核代码、数据结构。
用户进程无法直接访问,必须通过系统调用
3. 多任务与进程
2.1 多任务(并发)
多任务是让系统具备同时处理多个任务的能力。在 Linux 中有两种方式:
多进程
多线程
进程间通信(IPC)
宏观并行、微观串行:
多任务并发是 CPU 轮流快速切换不同任务,看起来像是同时执行。
4. 进程的调度与状态
4.1 进程调度算法
时间片轮询:每个进程轮流占用 CPU 一段时间。
先来先服务:先到的任务优先执行。
短作业优先:执行时间短的任务优先。
优先级调度:优先级高的任务先执行。
4.2 进程状态
状态 | 标记 | 描述 |
---|---|---|
运行态(用户状态运行、内核状态运行) | R | 正在 CPU 上执行 |
就绪态 | R | 等待 CPU 调度 |
可唤醒等待态 | S | 等待资源,可被唤醒 |
不可唤醒等待态 | D | 等待资源,不可被打断 |
暂停态 | T | 被挂起暂停执行 |
僵尸态 | Z | 进程结束但资源未回收 |
结束态 | X | 进程结束且资源已回收 |
操作系统进程进程三态图:
Linux操作系统的进程状态:
5. 进程相关命令
PID:进程的ID号
PPID :父进程ID号
父进程:产生子进程的进程称为父进程
子进程:父进程产生出来的新进程即为该父进程的子进程
1. ps -aux
ps -aux
查看进程相关参数:PID、状态、CPU占有率、内存占有率
ps -aux | grep ./a.out
| : 管道 :前面命令的输出作为后面命令的输入
grep : 字符串查找:在输入中查找和后面字符串相关的数据
2. top
top
动态查看进程的相关参数:CPU占有率、内存占有率
3. ps -ef
ps -ef
查看该进程的ID和父进程ID
4. pstree
pstree
查看进程的产生关系
pstree -p
查看进程的产生关系(有PID号)
pstree -sp 进程PID号
查看某个指定的进程的产生关系
5. kill
kill -信号的编号/信号的名称 PID
向进程发送信号,让进程的状态发生变化
kill -l
查看系统支持的信号
结束一个进程:
kill -9 PID
kill -SIGKILL PID
killall -9 进程名称
+表示前台进程
后台进程
jobs
查看当前终端的后台进程
fg 后台进程编号
让后台进程切换成前台进程
示例:
ps -aux | grep ./a.out
kill -9 PID
killall -9 进程名称
6. 进程编程接口
6.1 创建进程
#include <sys/types.h>
#include <unistd.h>pid_t fork(void);
功能:复制父进程,创建一个新的子进程。
特点:
子进程完整拷贝父进程的 0~3G 虚拟内存空间。
父子进程的栈区、数据区、文本区、堆区完全独立。
PID 不会被复制。
返回值:
> 0
:父进程,返回值是子进程的 PID
== 0
:子进程
-1
:创建失败
6.2 进程 ID
getpid()
:获取当前进程 PID
getppid()
:获取父进程 PID
6.3 进程退出与回收
退出:return
或 exit()
回收:wait()
、waitpid()
释放子进程资源
1.进程退出:return、exit()相关函数
1)main中return
2) exit ()、_exit() :结束一个进程
exit (0) : 正常退出
exit (非0) :由于进程产生了某种问题,需要主动退出进程
2.回收资源空间:wait()、waitpid()
僵尸进程:进程退出后,但其资源空间未被父进程回收
如何避免僵尸进程产生:
1. 子进程退出后,父进程及时为其回收资源空间
2. 让该进程成为一个孤儿进程,结束时被操作系统中的系统进程回收
孤儿进程:父进程先消亡,其对应的子进程成为一个孤儿进程,会被系统进程所收养
(守护类的进程)