1. 进程
1.1 进程定义

具体上,进程是一个具有一定独立功能的程序在某个数据集合上的一次动态执行过程(运行活动),是系统进行资源分配和调度的独立单位。进程是正在运行程序的抽象。进程的执行功能是由程序代码决定的。进程也被称为任务(Task or Job)。
为什么要有进程?
早先的操作系统是单道批处理的,但是CPU是高效率的,而IO是低速的,就会出现CPU要等待IO的情况;从而降低了实际效率。后来就引入多道批处理;而程序在执行的过程中又会因为共享资源而导致程序在执行的过程中相互限制;所有后来引入进程用来给程序提供一个抽象的概念,他能申请道系统资源并且独立给程序提供资源,从而解决原来的程序之间因为资源共享而相互限制的问题。这样就可以提高系统资源的利用率以及系统的处理能力。
作者:hello world
链接:https://www.zhihu.com/question/47877636/answer/1178912355
1.2 进程的组成
- 程序代码:一个进程需要执行的代码。
- 程序处理的数据:一个进程运行时,需要有处理的数据,数据放在内存中。
- 程序计数器(Program Counter,PC)的值,指示CPU下一条将要执行的指令:CPU需要知道现在要执行哪一条指令。
- 一组通用寄存器的当前值:如 堆(Heap)、堆栈(Stack)。
- 一组系统资源:如 打开的文件。
总之,进程包含了正在运行的一个程序的所有状态信息。
1.3 进程与程序的区别和联系
区别
- 进程是动态的,进程是程序的执行。程序是静态的,程序是有序代码的集合。另外,进程有内核态/用户态的区分。
- 进程是暂时的,进程是一个状态变化的过程。程序是永久的,只要硬盘不遭到破坏,程序就可以长久保存。
- 进程的组成包括程序代码、数据和进程控制块(Process Control Block,PCB)(即进程的状态信息)。
联系
- 程序是产生进程的基础。进程执行的功能在程序中都有具体的描述,并且受限于程序的代码。
- 程序的每次运行构成不同的进程。运行的程序在内存中处理的数据是不一样的,获得的资源也是不一样的,得到的效率就不一样。
- 进程是程序功能的体现。
- 通过多次运次,一个程序对应多个进程;通过调用关系,一个进程包括多个程序。
1.4 进程的特点
-
动态性:可以动态地创建、结束进程。
-
并发性:进程可以被独立地调度并占用CPU运行。
-
独立性:不同进程的工作不相互影响。
不影响的理解:操作系统(Operating System,OS)会不停地调度不同的进程执行,所以进程的执行时间可能会受到其他进程的影响,但是进程执行的结果是正确的。
如何保证进程执行的结果正确?页表。操作系统(OS)通过页表可以使不同的进程访问不同的地址空间。如果超过地址空间会产生页异常、页错误。操作系统(OS)给每一个进程分配一个页表,让每个进程在独立的地址空间上运行。
-
制约性:由访问共享数据/资源或进程间同步而产生的。
1.5 进程的控制结构
1.5.1 进程控制块(Process Control Block,PCB)
进程控制块(PCB)是OS管理控制进程运行所用的信息集合,是OS用于管理控制进程的一个专门数据结构。PCB记录着进程的基本情况,描述进程动态运行变化的过程。PCB是进程存在的唯一标志。(一一对应)。OS为进程生成一个唯一的PCB,意味着该进程创建。OS通过管理PCB来管理进程。OS回收PCB,意味着进程结束。
1.5.2 进程控制块包含哪些信息
- 进程描述信息。一个PCB唯一表示了一个进程,是进程的一个唯一的标识。通过PCB,OS可以识别出该进程正在执行哪一个程序,这个程序了几次。
- 进程标识符(Process Identifier,PID):唯一,通常是一个整数。
- 进程名:通常基于可执行文件名,不唯一。
- 用户标识符(User Identifier,UID):记录创建该进程的用户信息。
- 进程组关系:记录子进程、父进程、兄弟姐妹进程的关系信息。
- 进程的控制信息
- 当前状态
- 进程优先级(Priority)
- 代码执行入口地址
- 可执行程序的硬盘地址
- 运行统计信息(执行时间、页面调度)
- 进程间同步和通信
- 进程的队列指针
- 进程的消息队列指针
- 进程所有的资源和使用情况
- 虚拟地址空间的情况
- 打开文件列表
- CPU现场信息
- 用户可见寄存器:计算数据的寄存器,地址寄存器等。
- 控制和状态寄存器:程序计数器(PC)、程序状态字(PSW)等。
- 栈指针:进程调用/系统调用/中断处理和返回时需要使用栈指针。
- 调度和状态信息:OS调度进程的状态(就绪、运行、阻塞)占用CPU资源的信息。
- 指向该进程页表的指针。
Process management | Memory management | File management |
---|---|---|
Register | Pointer to text segment | Root directory |
Program Counter(PC) | Pointer to data segment | Working directory |
Program Status Word(PSW) | Pointer to stack segment | File description |
Stack Pointer(SP) | User ID | |
Process status | Group ID | |
Priority | ||
Process ID | ||
Parents group | ||
Signals | ||
Time when process started | ||
CPU time used | ||
Children’s CPU time | ||
Time of next alarm |
1.5.3 进程控制块(PCB)的组织方式
链表:动态过程。适合频繁创建结束进程。同一个状态的进程PCB组成一个链表。多个状态对应多种不同的链表,如就绪链表、运行链表和阻塞列表。
索引表:适合不频繁创建结束进程。
1.6 进程的生命期管理
进程的生命期:进程创建、进程运行、进程阻塞、进程唤醒、进程结束。
1.6.1 进程创建
- OS对初始化进程的数据、PCB、准备相关资源,就是进程的创建。
- 进程创建的时机:
- 系统初始时。
- 用户请求创建一个新进程时。
- 正在运行的进程执行了创建进程的系统调用。
1.6.2 进程运行
OS通过调度算法选择一个处于就绪状态的进程,让它占用CPU资源执行,此时该进程进入运行状态。
1.6.3 进程等待(阻塞)
进程从运行状态进入阻塞状态的时机:
- 请求并等待系统服务无法马上完成,如网络请求、IO。
- 启动某种操作,无法马上完成,如协调其他进程。
- 进程需要的数据没有到达。
进程只能自己阻塞自己,因为只有进程自己才能知道何时需要阻塞。
1.6.4 进程唤醒
进程唤醒的时机:
- 被阻塞的进程需要的资源被满足。
- 被阻塞的进程等待的事件到达。
- 将被阻塞的进程的PCB插入到就绪队列。
1.6.5 进程结束
正常退出(自愿)、异常退出(自愿)、致命错误退出(强制退出)、被其他进程所杀(强制退出)。
1.7 进程状态变化模型
- 创建态:创建了进程所必要工作(PID,PCB),尚未执行该进程。
- 运行态(Running Status):一个进程在CPU上运行的状态。
- 就绪态(Ready Status):一个进程获得了除CPU之外的一切所需资源,一旦得到CPU资源,即可进入运行状态。
- 等待态(Waiting Status):又称阻塞态,Blocked Status。一个进程正在等待某一事件而暂停执行的状态。
- 挂起态(Suspend Status):用于调节负载。进程不占用内存空间,该进程的映像交换到了磁盘上。
- 终止态(Terminated Status):终止执行后,进程进入该状态。进行数据统计工作,资源回收。
2. 线程
2.1 什么是线程(Thread)
线程(Thread)是进程重要的组成部分,在进程当中是一条指令执行控制流。一个进程中有多个线程,线程共享所属进程所拥有的资源。进程是用来管理资源的,将进程的另一部分功能交给线程来管理。
线程是轻量级进程。线程有自己的线程控制块(Thread Control Block, TCB)、程序计数器(PC)、栈指针(SP)、寄存器。
线程 = 进程 - 共享资源 = 指令执行序列。
为什么要使用线程?
在以前的OS中,使用多进程处理。在多任务环境中,不可能让所有任务都排队,处理完前面的任务才能处理后面的任务。要让用户感觉到所有任务都在执行,CPU就必须在多个进程之间频繁切换。问题是进程切换很耗时。所以一般OS中进程数量不能多。为了解决这个限制,提出了线程的概念。线程既保留了并发优点,又解决了进程切换代价(共享相同的地址空间)。
- 创建进程的开销较大:包括了数据、代码、堆、栈等。
- 进程的隔离性过强:进程间通信开销较大。
- 进程内部不支持并行。
2.2 线程的优缺点
优点
- 一个进程中可以同时存在多个线程。线程作为上下文切换的单位,开销较小。
- 各个线程之间可以并发地执行。
- 各个线程可以共享相同的地址空间、文件等资源,这使得线程之间数据传输和数据交换更加便利。
缺点
一个线程崩溃,可能会破坏与其他线程共享的资源,可能会导致所属进程的其他线程崩溃。
什么时候用线程和进程?
高性能计算:强调性能,用线程。
web浏览器:如果用多线程打开多个页面,可能某一个页面导致某个线程崩溃,进而引起整个浏览器崩溃。chriome浏览器采用的是一个进程打开一个页面。
2.3 线程和进程的区别
- 进程是资源分配的单位,线程是CPU调度的单位。线程继承了早期线程CPU调度这一属性。
- 进程拥有完整的资源,线程只能独占必不可少的资源(寄存器,栈指针)。
- 线程同样有就绪态、运行态、阻塞态,同样具有状态转换关系。
- 线程可以减少并发执行的时间和空间开销。
- 线程的创建时间比进程短。
- 线程的终止时间比进程短。
- 线程的上下文切换比进程快。
- 线程之间通信无须调用内核。
2.4 线程的实现方式
操作系统有两种CPU状态:
- 内核态(Kernel Model,Supervisor Mode):运行操作系统程序
- 用户态(User Model):运行用户程序
用户态–>内核态:中断/异常/陷入机制
内核态–>用户态:设置程序状态字

2.4.1 用户级线程(User Level Thread)
多个用户级线程对应一个内核级线程。
- 完全建立在用户空间的线程库上。用户级线程的建立、同步、销毁和调度完全在用户态中完成,不需要内核的帮助。
- 完全由运行时系统(Run-time System)管理。
- 内核管理的还是进程,内核只能看到进程,不知道线程的存在。

优点:
- 线程切换快。
- 调度算法是应用程序特定的,可以按照不同应用程序需求切换不同的线程。
- 用户级线程可运行在任何操作系统上,只需要在操作系统上支持响应的线程库即可。
缺点:
- 内核只能将CPU分配给进程。同一个进程中有多个线程,即使有多个CPU,也无法将线程分配到多个CPU上。
- 大多数系统调用时阻塞的。因此,内核阻塞整个进程,将会导致该进程的所有线程被阻塞。
- 内核级线程数据量大,开销大。
主流操作系统都采用一对一模型
- Windows、Linux、OS X。
2.4.2 内核级线程(Kernel Level Thread)
一个用户级线程(UT)对应一个内核级线程(KT)。
线程由内核创建,线程相关信息存放在内核中。一个用户级线程对应一个内核级线程。
- 内核管理所有线程,并向应用程序提供API接口。
- 讷河维护进程和线程的上下文切换。
- 线程的切换需要内核支持。
- 以线程为基础进行调度。
优点:内核管理简单。
缺点:可扩展性差,无法适应多核CPU的发展。
用于各种用户级线程库中。
2.4.3 混合模型
多个用户级线程对应多个内核级线程。
- 线程创建在用户空间完成。
- 线程调度等在内核态完成。
- 多个用户线程通过多路复用多个内核级线程。
优点:解决了可扩展性问题(多对一)和线程过多问题(一对一)。
缺点:管理更为复杂。
- Solaris在9之前使用该模型
- 9之后改为了一对一模型。
- 在虚拟化中得到了广泛应用。
2.5 进程调度
CPU调度:按一定的调度算法从就绪队列中选择一个进程把CPU的使用权交给被选中的进程。其任务是控制、协调进程对CPU的竞争。
CPU调度要解三个问题:
- 调度算法:按什么原则选择下一个执行的进程。
- 调度时机:何时进行选择。
- 调度过程(上下文切换):如何让被选中的进程在CPU上运行。
2.5.1 调度时机
内核对中断/异常/系统调用处理后,返回到用户态时。
- 进程正常终止、由于某种错误而终止。
- 新进程创建、一个等待进程编程就绪态。
- 当一个进程从运行态进入阻塞态。
- 当一个进程从运行态进图就绪态。
2.5.2 上下文切换(Context Switch)
进程切换就是一个进程先让出CPU,另一个进程占有CPU的过程。
停止当前运行的进程(运行态–>其他状态),并且调度其他进程(就绪态 -->运行态)。
-
进程运行时,其硬件状态保存在CPU上的寄存器(PC、PSW、SP、通用寄存器)中。
-
进程不运行时,这些寄存器的值保存在进程控制块(PCB)中。
进程切换主要包含两部分工作:
- 切换全局页目录以加载一个新的地址空间。
- 切换内核栈和硬件上下文,其中硬件上下文包括了内核执行新今晨需要的全部信息,如CPU相关寄存器。
另外上下文切换是有开销的:
- 直接开销:内核完成切换所用CPU时间。保存和恢复寄存器、切换地址空间都需要时间。
- 简介开销:高速缓存(Cache)、缓冲区缓存(Buffer Cache)和TLB(Translation Lookup Buffer)失效。
2.5.3 调度算法
1. 调度算法衡量指标
- 吞吐量 Throughput:每单位时间完成的进程数目。
- 周转时间TT(Turnaround Time):每个进程从提出请求到运行完成的时间。
- 响应时间RT(Response Time):从提出请求到第一次回应的时间。
2. 调度算法分类

3. 时间片(Time slice或quantum)
一个时间段,分配给调度CPU上的进程,确定了允许该进程运行的事件长度。
选择时间片,需要考虑以下因素:
- 进程切换的开销
- 对响应时间的要求
- 就绪进程的个数
- CPU的能力
- 进程的行为
参考文献
[1] 北京大学 Principles of Operating System 操作系统原理 by 陈向群
[2] 清华大学 操作系统原理 by 陈渝
[3] 深入Java虚拟机:JVM高级特性与最佳实践/周志明著 第3版
[4] Java Concurrency in Practice