文章目录
- 什么是进程
- 同一程序如何并发?
- Linux进程常用命令
- proc目录
- PCB进程控制块
- PCB包含的信息
- 两个进程间的关系
- 进程编程
- exec() 替换函数
- 子进程的运行过程
什么是进程
进程 = 程序运行的过程,系统进行资源管理和调度的独立单位。
程序由两部分组成:
- 静态区:
- 代码段:保存了代码。
- 数据段:保存全局变量等数据。
- 动态区:
- 堆区:保存程序动态申请的空间。
- 栈区:保存程序自动分配的内存。
但是单靠我们程序无法完成两件事:
- 多个程序同时运行(并发)。
- 单个程序同时多次运行。
所以需要操作系统来帮助程序运行。
同一程序如何并发?
对于同一程序的两个运行进程,程序代码都是一样的,CPU如何知道哪个进程对应哪块物理地址呢?
- 由于程序一样,所以参数都是一样的(比如va),通过同一映射 F(va) 得到的结果也是一样的,那就区分不了了。
- 如果还有一个唯一的参数,那就能确定了。这个唯一的参数就是进程号PID。
- 所以需要两个参数 F(va, z1), F(va, z2),这样就能映射出两个不同的物理地址了。
- CPU传出虚拟地址,经过协处理器处理参数再交由MMU,MMU接收两个参数后就转化为了物理地址。
- C13是协处理器,操作系统会用汇编更新协处理器的参数值来达到进程切换的目的,这就是进程的调度。
Linux进程常用命令
ps # 只展示前台进程
ps aux # 展示所有进程
pstree # Linux进程树
ps -ef # 显示父进程 PPID
PID = 1的进程是进程树的根节点,称为 祖先进程。
top # 动态显示所有进程
proc目录
保存了Linux系统中所有的 进程号PID,打开一个进程号目录就能看到里面的PCB信息。
PCB进程控制块
当CPU时间片到了,CPU会切换进程。CPU如何知道到手的任务数据存在哪、指令又执行到那一步了呢?于是操作系统给每个进程加上了一个数据结构:PCB(进程控制块),这个块里面涵盖了CPU所需的各种信息,以帮助CPU保存和恢复状态。
PCB包含的信息
- PID
- 进程控制管理信息:代码段与数据段地址等。
- 资源清单:I/O,内存等资源。
- 进程调度信息
- 处理机状态:寄存器值。
两个进程间的关系
- 由同一内核连接了不同的独立进程。
由两个毫不相干的进程通过内核通信。
进程编程
- printf()的输出暂存在缓冲区,在遇见换行符的时候才立即打印。
- fork() 函数复制一个当前进程的子进程,所有东西都一摸一样,所以连缓存区也原封不动的复制了一份,所以父子进程缓存区里都有这句话,所以打印两遍。
exec() 替换函数
exec 是一个用于执行程序的系统调用族,在操作系统(如 Linux 和 UNIX)中非常重要。它的功能是用一个新程序替换当前进程的执行内容,但不创建新的进程。也就是说,调用 exec 后,当前进程的代码和数据被新程序替换,但是该进程的 PID(进程ID) 和其他属性保持不变。
int execl(const char *path, const char *arg0, ..., NULL);
- path: 要执行的程序的路径。
- arg0, …, NULL: 传递给新程序的参数列表,必须以 NULL 结尾。
- 参数以单独的形式列出,通常第一个参数是程序名,后续参数是该程序的命令行参数。
在调用成功后,整个 静态区(代码区与数据区) 的所有后续代码都不会执行了,因为整个进程代码区被替换为了*path
这个文件,数据区也不复存在了。