1. 进程概念
什么是进程?
- 定义:进程是正在执行的程序。它是系统进行资源分配和调度的基本单位。
- 关键区别:
- 程序:是静态的,是存储在磁盘上的一组指令集合(如一个
.exe文件)。
- 进程:是动态的,是程序的一次执行活动,拥有自己的生命周期。
- 程序:是静态的,是存储在磁盘上的一组指令集合(如一个
- 进程的组成(进程实体的组成部分,称为PCB):
- 程序代码(文本段)
- 程序计数器:存放下一条要执行的指令的地址。
- 堆栈:用于存储临时数据,如函数参数、返回地址、局部变量等。
- 数据段:存储全局变量。
- 程序代码(文本段)
简单比喻:程序就像一个菜谱,而进程就是厨师按照菜谱烹饪的整个过程。菜谱是静态的,而烹饪过程是动态的,需要占用厨房(CPU)、食材(内存)、厨具(I/O设备)等资源。
2. 进程状态
一个进程在其生命周期中会处于以下几种状态之一:
- 新建:进程正在被创建。
- 就绪:进程已准备好运行,正在等待被操作系统分配CPU。
- 运行:进程的指令正在CPU上执行。
- 等待/阻塞:进程正在等待某个事件的发生(如I/O操作完成、信号量等),在事件完成前,即使分配CPU给它也无法执行。
- 终止:进程已经执行完毕,正在被系统回收资源。
状态转换经典图例:
新建 → (admitted) → 就绪 ↔︎
(scheduler dispatch / interrupt) ↔︎
运行 → (I/O or event wait) → 等待
→ (I/O or event completion) → 就绪 →
(exit) → 终止
3. 进程控制块
- 是什么:操作系统为了管理每个进程而创建的一个数据结构。PCB是进程存在的唯一标志。
- 作用:当进程切换时,操作系统通过保存和恢复PCB中的信息,来实现进程的“暂停”和“继续”。
- 包含信息:
- 进程状态
- 程序计数器
- CPU寄存器
- CPU调度信息(如优先级)
- 内存管理信息(如基址寄存器、界限寄存器)
- 记账信息(如CPU使用时间)
- I/O状态信息(如分配给该进程的I/O设备列表、打开的文件列表)
- 进程状态
4. 进程调度
调度队列
操作系统使用队列来管理处于不同状态的进程:
* 作业队列:系统中所有进程的集合。
*
就绪队列:在主内存中、已准备好并等待CPU的进程集合。
* 设备队列:等待某个特定I/O设备的进程集合。
调度器
- 长期调度器(作业调度器)
- 作用:决定哪些进程从硬盘被加载到内存(即加入就绪队列),从而可以竞争CPU。
- 调用频率低(秒/分钟级)。
- 控制多道程序的程度(内存中进程的数量)。
- 需要平衡:I/O密集型进程 和 CPU密集型进程。
- 作用:决定哪些进程从硬盘被加载到内存(即加入就绪队列),从而可以竞争CPU。
- 短期调度器(CPU调度器)
- 作用:从就绪队列中选择一个进程,并分配CPU给它。
- 调用频率非常高(毫秒级),必须非常快。
- 作用:从就绪队列中选择一个进程,并分配CPU给它。
- 中期调度器
- 作用:将暂时不运行的进程从内存换出到硬盘,以缓解内存压力;在需要时再换入。这引入了“挂起”状态。
上下文切换
- 是什么:当CPU从一个进程切换到另一个进程时,操作系统需要保存旧进程的PCB状态,并加载新进程的PCB状态的过程。
- 特点:上下文切换本身是系统开销,在此期间CPU没有执行任何用户进程的指令。切换速度依赖于硬件支持。
5. 进程操作
进程创建
- 进程通过
fork系统调用创建新的进程,形成进程树。
- 创建者称为父进程,被创建者称为子进程。
- 资源共享策略:
- 父进程和子进程共享所有资源。
- 子进程共享父进程资源的子集。
- 父进程和子进程不共享任何资源。
- 父进程和子进程共享所有资源。
- 执行顺序:
- 父进程与子进程并发执行。
- 父进程等待,直到其一个或多个子进程终止。
- 父进程与子进程并发执行。
- UNIX 示例:
fork():创建一个与父进程几乎完全相同的子进程(拷贝)。
exec():在fork()之后,用于将子进程的内存空间替换为一个全新的程序。
进程终止
- 正常终止(退出):进程执行完最后一条语句,调用
exit系统调用请求操作系统删除自己。
- 异常终止(中止):父进程可以终止其子进程的执行(
abort),原因包括:- 子进程超出了分配的资源的限制。
- 分配给子进程的任务不再需要。
- 父进程本身正在退出(可能导致级联终止)。
- 子进程超出了分配的资源的限制。
6. 进程间通信
两种基本模型
- 共享内存
- 思想:进程通过共享一块内存区域来直接读写数据。
- 优点:速度极快,因为数据不需要在内核和用户空间之间复制。
- 缺点:需要程序员自己处理同步问题(如使用信号量),否则会产生数据不一致。
- 典型问题:生产者-消费者问题。
- 思想:进程通过共享一块内存区域来直接读写数据。
- 消息传递
- 思想:进程通过操作系统提供的
send和receive原语来交换消息。
- 优点:易于实现,且操作系统自动处理了同步问题。
- 缺点:速度相对较慢,因为需要系统调用和数据复制。
- 思想:进程通过操作系统提供的
生产者-消费者问题(共享内存示例)
- 场景:一个或多个生产者进程生产数据,并放入一个大小固定的缓冲区中。一个或多个消费者进程从缓冲区中取出数据并消费。
- 挑战:
- 同步:当缓冲区满时,生产者必须等待;当缓冲区空时,消费者必须等待。
- 互斥:多个生产者和消费者同时操作缓冲区时,需要保证数据结构的完整性(例如,
in和out指针的更新不能冲突)。
- 同步:当缓冲区满时,生产者必须等待;当缓冲区空时,消费者必须等待。
- 代码核心:通过循环队列和
while循环检查(in+1) % BUFFER_SIZE == out(判断满)和in == out(判断空)来实现简单的同步。
消息传递的通信方式
- 直接通信:进程在
send和receive调用中直接指定对方的进程ID。send(P, message):发送给进程P。
receive(Q, message):从进程Q接收。
- 间接通信:进程通过一个中间实体——邮箱(或端口)——来通信。
send(A, message):发送到邮箱A。
receive(A, message):从邮箱A接收。
- 优点:解耦了发送者和接收者,灵活性更高。
消息传递的同步与缓冲
- 同步(阻塞 vs. 非阻塞):
- 阻塞发送:发送者会一直等待,直到消息被接收。
- 非阻塞发送:发送者发送消息后立即返回。
- 阻塞接收:接收者会一直等待,直到有消息到达。
- 非阻塞接收:接收者立即返回,无论有无消息。
- 阻塞发送:发送者会一直等待,直到消息被接收。
- 缓冲:消息队列的容量。
- 零容量:发送者必须等待接收者(称为“交会”)。
- 有限容量:队列满时,发送者必须等待。
- 无限容量:发送者永远不需要等待。
- 零容量:发送者必须等待接收者(称为“交会”)。
7. 客户端-服务器系统的通信
1. 套接字
- 定义:网络通信的端点,由 IP地址 +
端口号 唯一标识(如
161.25.19.8:80)。
- 通信:在两个套接字之间进行。
- 例子:你的浏览器(客户端)通过一个本地套接字与
google.com:443的套接字建立连接,进行HTTPS通信。
2. 远程过程调用
- 思想:使调用远程网络主机上的一个过程(函数/方法)像调用本地过程一样简单。
- 关键组件:
- 存根:在客户端,它扮演本地代理的角色。它负责将参数封装(列集)
成消息,并通过网络发送给服务器。
- 骨架:在服务器端,它接收请求,解封(散集) 参数,调用实际的服务器端方法,然后将结果封装返回给客户端。
- 存根:在客户端,它扮演本地代理的角色。它负责将参数封装(列集)
成消息,并通过网络发送给服务器。
3. 远程方法调用
- 思想:RPC的面向对象版本,是Java的核心特性。
- 特点:允许一个Java程序调用另一个(可能在不同机器上的)JVM中的对象的方法。
本章核心概念总结
- 进程 vs. 程序:动态 vs. 静态。
- 进程状态:新建、就绪、运行、等待、终止。
- PCB:进程的“身份证”,保存了进程的所有管理信息。
- 上下文切换:进程切换的核心机制,有系统开销。
- 进程树:通过
fork和exec创建和修改进程。
- IPC两大模型:
- 共享内存:快,但需要自己处理同步。
- 消息传递:慢,但由OS处理同步,更安全。
- 共享内存:快,但需要自己处理同步。
- 经典同步问题:生产者-消费者问题。
- 网络通信:套接字、RPC、RMI 是不同层次的进程间通信(跨越网络)的抽象。
第三章课后练习题
进程被定义为?
A. 一个程序
B. 一个作业
C. 一段程序代码
D. 一个正在执行中的程序下列哪个是可能的进程状态转换?
A. 新建 -> 终止
B. 运行 -> 等待
C. 等待 -> 运行
D. 运行 -> 新建考虑一台计算机内部只有一个CPU,实际上有多少个作业能被CPU同时执行?
A. 1
B. 2
C. 3
D. N给定一个有n个进程的系统,这些进程有多少种可能的调度顺序?
A. n-2
B. n-1
C. n
D. n!如果一个进程正在等待被分配给处理器,它必须处于______状态。
A. 就绪
B. 等待
C. 运行
D. 终止在UNIX中,一个新的进程是通过______系统调用创建的。
A. exit()
B. wait
C. exec()
D. fork()用于在运行中的程序和操作系统之间传递参数的方法是什么?(提示:第三章内容,三种方法:通过寄存器、通过内存块、通过栈)
参考答案:
1. D 2. B 3. A 4. D 5. A 6. D
2. 通过寄存器;通过内存块;通过栈。
如果您喜欢我的文章,可以考虑打赏以支持我继续创作.