持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第10天,点击查看活动详情
注意:下面标星*的表示会在以后补充
概念
Multiprogramming
什么是多道程序设计?
一种操作模式,由一个处理器交替执行两个或多个程序。
好处:提高CPU利用率。 通过允许多个程序“同时”驻留在主内存中,可以共享CPU,这样当一个程序启动I/O操作时,可以将另一个程序分配给CPU,从而提高CPU利用率。
多道程序设计的道数degree:同时加载到内存中的进程数称为多道程序设计的道数
concurrency并发
并发的好处:
- 更好的资源利用率
- 一个应用程序未使用的资源可以被其他应用程序使用。
- 更好的平均响应时间
- 无需等待其他应用程序完成。
进程
进程是运行程序的操作系统抽象。
进程与程序
进程与程序的关系:
- 进程:正在执行的程序
- 程序 = 静态文件
- 进程 = 执行程序=程序+执行状态。
- 进程是程序的实例。
- 不同的进程可以运行同一程序的不同实例(如打开两个浏览器)
8个区别:
- 程序包含一组用于完成特定任务的指令。进程是正在执行的程序的实例。
- 程序是一个消极实体,因为它驻留在辅助内存中。进程是一个活动实体,因为它是在执行期间创建并加载到主存中的。
- 程序存在于单个位置,并继续存在,直到被删除。进程存在的时间有限,因为它在任务完成后会被终止。
- 程序是一个静态实体。流程是一个动态实体。
- 程序不需要任何资源,它只需要存储指令的内存空间。进程对资源的要求很高,在其生命周期中需要CPU、内存地址、I/O等资源。
- 程序没有任何控制块。进程有自己的控制块,称为进程控制块。
- 程序有两个逻辑组件:代码和数据。除了程序数据外,进程还需要管理和执行所需的其他信息。
- 程序本身不会改变。许多进程可以执行单个程序。它们的程序代码可能相同,但程序数据可能不同。
进程的创建和终止
进程创建事件:
- 系统初始化
- 执行进程创建系统调用
- 创建新进程的用户请求
- 批处理作业的启动
进程终止事件:
Normal exit (voluntary)
Error exit (voluntary)
Fatal error (involuntary)
Killed by another process (involuntary)
*进程的层次结构
进程的状态
三种状态:运行、就绪、阻塞 running, ready, block
- running
- 进程当前正在使用CPU。
- ready
- 当前正在等待分配给CPU。
- 也就是说,进程可能正在运行,但另一个进程正在使用CPU,在等待另一个的进程。
- block
- 进程正在等待事件,例如完成输入/输出、计时器关闭、资源可用等。
状态变化:
- 运行->阻塞: 进程发现它无法继续。
- 运行->就绪:就绪->运行: 由process scheduler引起。
- 阻塞->-就绪: 进程正在等待的外部事件发生。
进程的实现
进程控制块(PCB,Process Control Block)
也叫做进程表项,是操作系统内核中的一种数据结构,包含管理特定进程所需的信息,OS为每个进程维护一个PCB,PCB由整数进程ID标识
PCB在一个进程的整个生命周期内保持不变,一旦进程终止,PCB就会被删除。 PCB的体系结构完全依赖于操作系统,在不同的操作系统中可能包含不同的信息。
PCB包含的信息: 进程ID 操作系统中每个进程的唯一标识。 状态 进程的当前状态。 指针 指向父进程的指针。 优先事项 流程的优先级。 程序计数器 CPU寄存器 各种CPU寄存器,其中需要存储进程以执行运行状态。 输入/输出信息 输入/输出状态信息包括分配给进程的输入/输出设备列表。Account信息 这包括用于进程执行的CPU数量、时间限制等。
状态队列
操作系统维护一组队列,这些队列表示系统中所有进程的状态。
- 每个状态通常有一个队列,例如Ready队列,等待IO队列。
- PCB根据目前状态排到对应状态队列当中
- 当进程改变状态时,其PCB将从一个队列中断开链接,并链接到另一个队列。
PCB和状态队列:
- PCB是数据结构,在操作系统内存中动态分配。
- 创建进程时,将为其分配一个PCB,对其进行初始化,并将其放置在正确的队列中。
- 随着进程的计算,其PCB从一个队列移动到另一个队列。
- 当进程终止时,其PCB被释放。
进程表
进程表或PCB表:
- OS维护一个进程表,每个条目都是PCB。
- PCB表的大小决定了系统的并发度。
- 两种组织形式:Link Index
进程的结构
- User Code
- User Data
- User Stack: Used for procedure call and parameter passing.
- PCB (Metadata)
上下文切换 Context Switch
将CPU从一个进程切换到另一个进程,由调度器执行。
过程:
- 保存旧进程的PCB状态;
- 加载新进程的PCB状态;
- 刷新内存缓存;
- 更改内存映射(TLB);
开销较大,且需要硬件支持
线程
一个进程希望进行不同活动,并共享内存
定义:进程内的顺序执行流 A sequential execution stream within a process(也称为轻量级进程)。
特性:
- 进程中的所有线程共享相同的地址空间和操作系统资源。
- 线程共享内存,因此可以直接通信
- 每个线程都有自己的栈(局部变量)、CPU寄存器、PC等。
优势:
- 响应性
- 多线程交互应用程序允许程序继续运行,即使部分程序被阻止或执行冗长的操作。
- 资源共享
- 同一进程中的线程可以更方便、更高效地共享数据和其他资源(无需复制或消息)。
- 进程内的线程彼此不受保护(线程来自同一个进程,因此不存在不同用户之间)
- 经济:线程比进程更轻。
- 创建一个线程比一个进程便宜(大约10-20倍)。
- 在同一进程中切换到不同的线程更便宜(5-50倍)。
- 可扩展性
- 更好地利用多处理器体系结构。 左边代表一个进程中线程共享的内容,右边代表每个线程独有的内容
阻塞和非阻塞调用:
- 阻塞系统调用
- 通常与I/O相关:read()、fread()、getc()、write()
- 直到呼叫完成才返回。
- 进程/线程切换到阻塞状态。
- 当I/O完成时,进程/线程准备就绪。
- 使用非阻塞系统调用进行I/O
- 异步输入/输出
- 复杂的
- 一旦I/O启动,调用方将返回,并继续。
- 一旦输入/输出完成,就会向调用者发送一个中断。
线程的实现
线程状态同进程,包含运行。就绪、阻塞,切换也相同
线程控制块(TCB)基本同PCB,线程表基本同进程表
不同点:
- 线程:处理器状态
- 进程:地址空间和操作系统资源(打开的文件等),没有执行状态
上下文切换: 在块内切换线程是一种简单的线程切换。 跨块切换线程需要更改内存和I/O地址表,更改地址空间,可能使缓存无效
TCB现在是上下文开关的单元。
- 就绪队列、等待队列等现在包含指向TCB的指针。
- 上下文切换导致CPU状态复制到TCB或从TCB复制CPU状态。
线程和进程
相同点:
- 线程共享CPU,一次只运行一个线程。
- 进程内的线程也按顺序执行。
- 线程可以创建子线程。
- 线程可以处于以下几种状态之一:运行、就绪或阻塞。
- 线程也有程序计数器、堆栈、寄存器和状态
不同点:
- 进程
- 与单个程序的执行有关的资源所有权单位 Unit of resource ownership。
- 可以包含多个执行线程。
- 进程在很大程度上是独立的,而且可能来自于不同用户,有保护机制
- 昂贵的创建。
- 昂贵的上下文切换。
- 线程
- Unit of execution。
- 属于进程。
- 线程是同一“job”的一部分,并且积极而密切地协作。
- 廉价创建
- 廉价的上下文切换。
*POSIX线程
用户级线程 User-level Threads
- 为了使线程既便宜又快速,它们需要在用户级别实现。
- 用户级线程完全由运行时系统(线程库)管理
- 用户级线程小而快。
- 线程仅由PC、寄存器、堆栈和小型线程控制块(TCB)表示。
- 通过过程调用创建新线程、在线程之间切换和同步线程。
- 没有内核参与。
- 用户级线程操作比内核线程快100倍。
- 所有操作(创建、销毁、屈服yield)都是正常的过程调用(procedure calls)
用户级线程的优点
- ULTs可以在任何操作系统上运行。
- 只需要一个线程库。
- ULT创建和管理速度很快。
- 线程上下文切换比进程上下文切换快得多
- 不需要内核模式开关。
- 仅保存/加载寄存器。
- 线程可能会自动产生(本地调用)。
- 在用户级线程中,调度可以是特定于应用程序的。
- 可能支持每个进程定制的调度算法。
- 更好的可扩展性。
用户级线程的问题:
- 大多数系统调用都是阻塞的,内核会阻塞进程。如果一个用户级线程执行阻塞操作,则整个进程将被阻塞。
- 解决:
- 1、可以将系统调用更改为所有非阻塞,需要重写操作系统大部分。
- 2、提前告知调用是否会阻塞。需要重写系统调用库的部分。
- 线程可能垄断CPU(进程中没有时钟中断)。
- 内核只能将进程分配给处理器。而同一进程中的两个线程不能同时在两个处理器上运行。
内核级线程 Kernel-level Threads
OS直接管理(而不是由进程管理)的线程称为内核级线程或轻量级(lightweight)进程。
内核级线程的优点:
- 如果进程中的一个线程被阻塞,内核可以调度同一进程的另一个线程。
- 内核例程本身可以是多线程的。
- 内核可以在SMP多处理器上的不同CPU上调度多个线程。
内核级线程的缺点:
- 调度、创建和删除线程的速度比用户级线程慢。
- 在同一进程中,控制权从一个线程转移到另一个线程需要切换到内核的模式。
- 操作系统必须随着线程数量的增加而扩展。
| ULTs | KLTs |
|---|---|
| 内核级线程用户级线程的创建和管理速度更快。 | 内核级线程的创建和管理速度较慢(因为操作系统本身参与导致)。 |
| 通过用户级的线程库实现。 | 操作系统支持创建内核线程。 |
| 操作系统支持创建内核线程。 | 内核级线程特定于操作系统。 |
| 无法由操作系统调度。 | 可以由操作系统调度。 |
| 多线程应用程序无法利用多处理。 | 内核例程本身可以是多线程的。 |
可以在多处理器中的不同处理器上调度相关的内核级线程。
混合实现
内核级线程和用户级线程的混合:m-to-n线程映射
- 应用程序创建m个线程。
- OS提供了n个内核线程池。
- 一些内核级线程会被用户级线程多路复用