发布网友 发布时间:2023-08-07 16:48
共1个回答
热心网友 时间:2023-09-14 22:58
计算机的物理资源有限。
多个程序在计算机上同时运行,它们不可能连续地在处理器上运行或占用全部内存,因此需要进程的抽象在用户的一侧隐藏上下文切换等细节。
进程作为运行的程序的抽象,包含了一个程序的运行状态和这个程序所用的抽象内存及其中存储的数据。我们将后一部分,即一个进程可以使用的全部内存的地址和它们存储的数据,称为这个进程的地址空间(address space)。我们可以将进程笼统地看做是一个或多个线程与一个地址空间的结合。
上面提到的都是进程在用户一侧的抽象,但我们还没有考虑过在系统一侧我们需要什么数据结构来实现这一抽象。这一节中我们就将会探索进程在系统中的实现。
为了实现上述的第一个目的,即在进程中存储其运行状态,我们将在进程中存储处理器状态寄存器、指令计数器、栈指针、通用寄存器等代表了进程目前的运行状态的值。由于现代计算机中往往有多个核或多个处理器,我们的程序可以达到并行(parallelism,即在物理时间上同时运行,区别于多个进程在处理器上的并发(concurrency)),,因此同一个进程可能同时包含有多个不同的运行状态。为了更好地区分进程在一个处理器上的运行状态和进程本身的运行状态,我们在此引入线程概念。每个线程拥有一个线程控制块(thread control block, TCB),,用来存储我们上述提到的处理器状态寄存器、指令计数器、栈指针、通用寄存器等数值,但同一个进程中的所有线程都共享同一个地址空间。
一个用户进程所看到的内存空间是抽象的,区别于实际的物理内存,因此为了支持进程从抽象内存获取物理内存中存储的信息,我们需要在进程中包含从抽象内存向物理内存的映射,即该系统所用的地址转换方法所需要的信息。地址转换有很多种不同方法,包括分页存储、分段存储等,它们都需要不同的信息来实现地址转换;
以最为简单的 Base and Bound 为例。
在 Base and Bound 方法中,系统将一段连续的物理内存分配给一个进程,Base 代表基地址,即系统分配给一个进程的可用内存的起始地址,Bound 代表这个进程可用的内存的最高地址。为了读写物理内存,我们将基地址与抽象内存地址相加,获得实际地址;只要实际地址不大于 Bound,内核就会允许进程进行该操作。因此在这个方法中,为了实现进程地址空间的抽象,进程在系统一侧的数据结构中必须包括这段可用的内存的基地址、可用长度。
为了能在一个进程开始运行的时候方便地载入上面提到的两方面的数据,我们需要一个数据结构来包含这些数据。这个数据结构就是 进程控制块(Process Control Block, PCB),。对于内核来说,它是进程存在的唯一标识。进程控制块中存储的信息除了上面提到的实现地址转换的信息和表示运行状态的线程信息以外,还包括了很多系统在调度进程时需要的信息,比如进程号、进程所处状态(我们将在下一节中更多地解释进程可能所处的状态与不同状态间的切换)、进程的优先级等等。需要注意的是,我们不会将整个地址空间中包含的地址及其数据都存储在进程控制块里;我们只需要可以帮助我们从抽象内存地址获得实际物理地址的方法,而实际数据仍然存储在内存的对应位置中。
由于进程控制块中的信息包含了优先级、基地址、可用地址范围等用户进程不应该有权限修改的信息,用户进程不应该有权限修改进程控制块。因此我们将进程控制块存储在内核空间中。
在上一节中我们提到,进程控制块中包含了进程的状态;那么,什么是进程的状态呢?我们已经提到过,一个进程可能在运行一段时间后被切换出去,一段时间后继续运行。显然,进程至少需要两个状态——运行态(running)、就绪态(ready)。
进程在运行态中运行一段时间后被切换出去,排入就绪队列,等待继续运行。在三态模型中,进程还有一个状态,即 等待态(wait),。在这个状态中,进程在等待某一事件完成,不会被排入就绪队列,直到该事件发生后,进程才会被排入就绪队列,可能被选为下一个运行的进程。这一等待事件可能包括等待系统调用完成,等待获得某一个锁或收到某一信号量的信号等等,
你只需要知道,处于就绪态的进程不会因为遇到任何事件而无法进入等待态;处于等待状态的进程在事件发生后考虑到优先级等问题,必须先回到就绪状态而不能直接运行。
五态模型也是一种常见的进程状态转换模型。相比三态模型,五态模型多引入了新建态(new)和终止态(exit)。
定义这两种状态可以帮助我们避免一些我们不想看到的情况。
比如,如果我们允许一个进程在获得全部资源以前就进入就绪队列,那么一个新进程可能在未获得全部资源前就开始运行,而产生错误。(这是因为我们是在另一个进程里通过系统调用创造了这个新的进程)
同样的,如果一个进程 A 创建了另一个进程 B ,想要等待进程 B 运行完毕后从中获得一些信息,那么终止态的缺失可能导致进程 B 率先运行完毕后被系统撤销,使得进程 A 无法从进程 B 处获得任何信息。
UNIX 系统中,如果发生一个进程创建另一个进程的情况,那么在老进程从新进程获取信息前,新进程会一直停留在终止态;如果新进程终止后,仍在运行的老进程没有从新进程获取信息,那么新进程就会成为我们所说的“僵尸进程”,停留在系统内存中,导致系统变慢。
除去图片中虚线的两个状态,剩下的三个状态就是我们之前提到的三态模型。注意各个状态之间转换的条件。