操作系统 ch3 进程 processes

概念

在执行的程序。不只是执行中的程序代码,还包括当前活动(通过程序计数器的值和处理器寄存器的内容来表示)、进程堆栈段(包括临时数据如函数参数、返回地址和局部变量)、数据段(包括全局变量)、堆(在进程运行期间动态分配的内存)。
内存中的进程结构:
image

进程由代码(可能共享)、数据、状态组成。

多个进程与一个程序相关时,他们的文本段是共享的

Trace of the Process

进程的指令序列为Trace

Dispatcher负责进程的切换

User view of processes

Process Creation

  1. 父进程可以与子进程一起执行
  2. 父进程也可以等子进程结束再执行

进程树image

两种方式:

  1. fork() 系统调用创建新进程,两个进程都继续执行 fork 之后的指令
  2. exec() 系统调用用新程序替换进程内存空间

Process Termination进程终止

exit 主动

进程执行完成最后语句,使用 exit 系统调用来请求操作系统删除自身。

  1. 可以通过 wait 向父进程返回状态值
  2. 所有进程资源被释放

abort 被动

父进程执行 abort 等系统调用终止子进程。有如下等原因:

  1. 使用超过分配到的资源
  2. 被分配的任务已不再需要
  3. 父进程终止

Kernel view of processes

PCB

一个进程在运行时包含很多信息,如标识符、状态、程序计数器、内存指针、上下文数据、输入输出状态信息等。这些信息存储在进程控制块(Process Control Block, PCB) 中。PCB 是进程的快照。
image

进程状态

进程有如下状态:

  1. new 新的: 进程正在被创建
  2. ready 就绪: 等待分配处理器
  3. running: 正被执行
  4. waiting: 等待某个事件的发生(如 I/O 完成)
  5. terminated 终止: 完成执行
    image

进程创建

当操作系统想要创建新的进程时,要:

  1. 分配唯一的进程标识符
  2. 为进程分配空间
  3. 初始化PCB
  4. 设置适当的链接
  5. 创建或扩展其他数据结构

进程切换

image
image

该过程也成为上下文切换 context switch。
进程切换的具体步骤:

  1. 保存处理器的上下文,包括程序计数器和其他寄存器
  2. 更新正在运行的进程的PCB
  3. 将PCB移到合适的队列
  4. 选择另一个进程执行
  5. 更新被选择进程的PCB
  6. 更新内存管理数据结构
  7. 还原所选进程的上下文

进程调度队列 Process Scheduling Queues

  1. Job queue – set of all processes in the system.

  2. Ready queue – 主存中准备就绪并等待执行的进程集合image

  3. Device queues – 等待 IO 设备的进程集合
    image

PCB 随着其状态的变化在进程中移动。

调度程序 Schedulers

Long-term scheduler(job scheduler)

从缓冲池中选择进程装入内存中以准备执行。控制多道程序设计的程度(内存中的进程数量)。执行不频繁,有更多时间选择进程。比如进程有I/O-bound(IO操作多) 和 CPU-bound(cpu操作多)两种,在选择进程时需要合理的选择两种进程。

Short-term scheduler(CPU scheduler)

从准备执行的进程中选择接下来应执行的进程并分配 CPU。
必须频繁为cpu 选择进程,执行要快。

进程间通信 Interprocess Communication(IPC)

协作进程Cooperating process:会被其他进程的执行影响或影响其他进程。
独立进程Independent process:与其他进程无关
进程协作的优点:

  1. 信息共享 Information sharing
  2. 提高运算速度 Computation speed-up
  3. 模块化Modularity
  4. 方便 Convenience

IPC允许协作进程交换数据与信息,即进行进程间通信。
进程间通信有两种方法:

  1. 消息传递。通常用系统调用来实现,适用于交换数量少的数据。
  2. 共享内存。仅在建立共享内存区时用到系统调用,速度更快。
    image

共享内存系统——生产者-消费者问题

生产者进程产生信息供消费者进程消费。

Shared data
#define BUFFER_SIZE 10
Typedef struct {
. . .
} item;
item buffer BUFFER_SIZE;
int in = 0;
int out = 0;

in 指向缓冲中下一个空位,out 指向缓冲中第一个满位。
Producer process

item nextProduced;
while (1) {
while (((in + 1) % BUFFER_SIZE) == out)
; / do nothing /
bufferin = nextProduced;
in = (in + 1) % BUFFER_SIZE;
}
Consumer process
item nextConsumed;
while (1) {
while (in == out)
; / do nothing /
nextConsumed = bufferout;
out = (out + 1) % BUFFER_SIZE;
}

这种方法最大缓冲项数为 BUFFER_SIZE - 1.

消息传递系统

信息传递工具提供至少两种操作:

  1. send(message) – 消息可以定长、变长
  2. receive(message)

如果进程 P,Q 想要通信,那么一定要有通信线路(communication link)来实现彼此发送、接收消息。
通信线路的实现有物理实现和逻辑实现,这里仅说明逻辑实现的一些方法:

  1. 直接或间接通信
  2. 同步或异步通信
  3. 自动或显式缓冲

直接通信 Direct Communication

进程必须明确命名接收者、发送者。
send (P, message) – 发送消息到进程 P。
receive(Q, message) – 接收消息从进程 Q。

间接通信 Indirect Communication

通过邮箱 mailbox 或者端口发送接收消息。每个邮箱都有唯一标识符。要进行通信的进程要共享至少一个邮箱。
send(A, message) – send a message to mailbox A。
receive(A, message) – receive a message from mailbox A。
问题:P1, P2, and P3 共享邮箱 A.
P1发送信息; P2 and P3 谁接收信息?
解决方案:

  1. 一个线路最多关联两个进程
  2. 一次最多允许一个进程去接收
  3. 系统随便选择一个进程接收消息。给发送者标识接受者。

同步 Synchronization

消息传递可以是阻塞 blocking、非阻塞 Non-blocking 的,即同步 synchronous、异步asynchronous。
发射与接收可以进行任意的组合。

缓冲

通信进程交换的信息都停留在临时队列中,队列有三种方式:

  1. 0容量。线路中不能有消息在等待,故必须阻塞发送,直到接收者收到信息
  2. 有限容量。
  3. 无限容量。

0容量为没有缓冲的消息系统,其他成为自动缓冲。

管道 pipe

管道本质上就是一个文件,前面的进程以写方式打开文件,后面的进程以读方式打开。这样前面写完后面读,于是就实现了通信。
ls | wc 在ls 和 wc 进程之间创建了管道。

posted @ 2022-05-11 09:51  流云轻响  阅读(91)  评论(0)    收藏  举报