北航考研
2023年11月16日 一稿
2024年 3月 6日 二稿
2024年 3月26日 三稿
进程本身是一个比较抽象的概念,它不是实物,看不见、摸不着
4.1 进程的概念
4.1.1 程序的顺序执行
4.1.2 程序的并发执行和特征
4.1.3 Bernstein条件
4.2.1 进程的特征
4.2.2 进程与程序的区别
**fork()和exec()是操作系统中用于进程控制的系统调用,它们在创建和修改进程方面发挥着重要作用**。这两个函数为程序员提供了灵活控制进程的能力,使得多任务并行执行成为可能。以下将详细解释fork()和exec()的作用:
- **fork()的作用**
1. **创建新进程**: fork()函数用于创建一个与当前进程(父进程)几乎完全相同的新进程(子进程)。新进程拥有与父进程相同的代码段、数据段和堆栈段[^1^]。
2. **父子进程关系**: 通过fork()创建的子进程与父进程存在父子关系。父子进程在系统中有各自独立的进程ID(PID),但它们的PPID(Parent Process ID)相同,都是原父进程的PID[^3^]。
3. **写时复制技术**: 现代操作系统通常使用写时复制(Copy-On-Write,COW)技术优化fork()操作。在fork()调用时,子进程并不立即获得父进程数据的物理拷贝,而是两者共享同一内存页面。只有当其中一个进程试图修改数据时,才会进行实际的物理复制[^5^]。
4. **并发执行**: fork()创建的子进程与父进程并发执行,这意味着两者可以同时运行并竞争CPU资源。这种并发性使得多个任务能够在同一时间段内得到处理[^1^][^3^]。
- **exec()的作用**
1. **替换进程映像**: exec()族函数用于在当前进程中加载并执行一个新程序。此操作会完全覆盖当前进程的内存空间,包括代码段、数据段和堆栈段,用新程序的对应部分替代[^4^]。
2. **进程ID保持不变**: 尽管执行了新的程序,但调用exec()后,新程序的进程ID保持不变。这样,从系统的视角看,尽管程序内容已变,但仍然视为同一个进程[^2^]。
3. **文件描述符继承**: 调用exec()时,已打开的文件描述符默认保持打开状态,除非明确指定关闭。这允许新程序继续使用之前进程已经打开的文件、网络连接等资源[^4^]。
4. **环境变量传递**: exec()族函数允许将旧进程的环境变量传递给新程序。这对于新程序继承配置信息和运行上下文非常重要。
综上所述,fork()和exec()在进程控制中扮演着关键角色,分别负责创建新进程和替换进程映像。这些系统调用不仅提高了计算机资源的利用率,还为程序员提供了强大的多任务处理能力。
4.2.3 进程的组成
进程是一个独立的运行单位,也是操作系统进行资源分配和调度的基本单位。它由以下三部分组成,其中最核心的是进程控制块(PCB)
进程控制块
程序段
程序段就是能被进程调度程序调度到CPU执行的程序代码段。注意,程序可被多个进程共享,即多个进程可以运行同一个程序。
数据段
一个进程的数据段,可以是进程对应的程序加工处理的原始数据,也可以是程序执行时产生的中间或最终结果。