目录
1.1进程
1.1.1进程的概念
进程是进程实体的一次执行过程,是系统进行资源分配和调度的一个独立单位。
并发进程的运行结果具有不可再现性
进程实体(进程映像) 就是进程动态执行的一个静态切片,能够准确描述程序此刻的运行状态。它包括PCB、程序段、相关数据段。
父进程与子进程:允许一个进程创建另一个进程,此时创建者称为父进程,被创建的进程称为子进程。子进程可以继承父进程所拥有的资源。当子进程被撤销时,应将其从父进程那里获得的资源还给父进程;在撤销父进程时,通常也会同时撤销其所有的了进程。
1.1.2进程的组成
进程由PCB(进程控制块)、程序段、数据段组成。
PCB(进程控制块):PCB是进程实体的一部分,是进程存在的唯一标志
- 进程创建时,操作系统为它新建一个PCB,该结构之后常驻内存,任意时刻都可以存取,并在进程结束时删除;
- 进程执行时,系统通过其PCB了解进程的现行状态信息,以便操作系统对其进行控制和管理;
- 进程结束时,系统收回其PCB,该进程随之消亡
C语言编写的程序在使用内存时一般分为三个段,它们一般是正文段(代码和赋值数据段)、数据堆段和数据栈段。二进制代码和常量存放在正文段,动态分配的存储区在数据堆段,临时使用的变量在数据栈段。
1.1.3进程的特征
1.1.4进程的状态
1.1.4.1不同进程状态的概念
1创建态
进程正在被创建时,它的状态是“创建态”,在这个阶段操作系统会为进程分配资源、初始化PCB;当进程创建完成后,便进入“就绪态”
2就绪态
处于就绪态的进程已经具备运行条件,但由于没有空闲CPU,就暂时不能运行
3运行态
如果一个进程此时在CPU上运行,那么这个进程处于“运行态”
4阻塞态
在进程运行的过程中,可能会请求等待某个事件的发生(如等待某种系统资源的分配,或者等待其他进程的响应)。在这个事件发生之前,进程无法继续往下执行,此时操作系统会让这个进程下CPU,并让它进入“阻塞态” ,此时CPU空闲,又会选择另一个“就绪态”进程上CPU运行
5终止态
一个进程可以执行 exit 系统调用,请求操作系统终止该进程。 此时该进程会进入“终止态”,操作系统会让该进程下CPU, 并回收内存空间等资源,最后还要回收该进程的PCB。 当终止进程的工作完成之后,这个进程就彻底消失了
1.1.4.2不同状态间的转换
1.1.5进程的组织
1链接方式
2索引方式
1.1.6进程的控制
进程控制的主要功能是对系统中的所有进程实施有效的管理,它具有创建新进程、撤销己有进程、实现进程状态转换等功能。在操作系统中,进程控制一般用原语来实现
1进程的创建
在操作系统中,终端用户登录系统、作业调度、系统提供服务、用户程序的应用请求等都会引起进程的创建。操作系统创建一个新进程的过程如下(创建原语):
- 为新进程分配一个唯一的进程标识号,并申请一个空白PCB (PCB是有限的)。若PCB申请失败,则创建失败。
- 为进程分配其运行所需的资源,如内存、文件、I/O设备和CPU时间等(在PCB中体现)。这些资源或从操作系统获得,或仅从其父进程获得。如果资源不足(如内存),则并不是创建失败,而是处于创建态,等待内存资源。
- 初始化PCB,主要包括初始化标志信息、初始化CPU状态信息和初始化CPU控制信息,以及设置进程的优先级等。
- 若进程就绪队列能够接纳新进程,则将新进程插入就绪队列,等待被调度运行。
2进程的终止
引起进程终止的事件主要有:
- 正常结束,表示进程的任务己完成并准备退出运行。
- 异常结束,表示进程在运行时,发生了某种异常事件,使程序无法继续运行,如存储区越界、保护错、非法指令、特权指令错、运行超时、算术运算错、I/O故障等。
- 外界干预,指进程应外界的请求而终止运行,如操作员或操作系统干预、父进程请求和父进程终止。
操作系统终止进程的过程如下(终止原语):
- 根据被终止进程的标识符,检索出该进程的PCB,从中读出该进程的状态。
- 若被终止进程处于运行状态,立即终止该进程的执行,将CPU资源分配给其他进程。
- 若该进程还有子孙进程,则通常需将其所有子孙进程终止(有些系统无此要求)。
- 将该进程所拥有的全部资源,或归还给其父进程,或归还给操作系统。
- 将该PCB从所在队列(链表)中删除。
3进程的阻塞
正在执行的进程,由于期待的某些事件未发生,如请求系统资源失败、等待某种操作的完成、新数据尚未到达、无新任务可做等,进程便通过调用阻塞原语(Block),使自己由运行态变为阻塞态。可见,阻塞是进程自身的一种主动行为,也因此只有处于运行态的进程(获得CPU),才可能将其转为阻塞态。阻塞原语的执行过程如下:
- 找到将要被阻塞进程的标识号(PID)对应的PCB
- 若该进程为运行态,则保护其现场,将其状态转为阻塞态,停止运行。
- 将该PCB插入相应事件的等待队列,将CPU资源调度给其他就绪进程。
4进程的唤醒
当被阻塞进程所期待的事件出现时,如它所期待的I/O操作已完成或其所期待的数据已到达,由有关进程(比如,释放该I/O设备的进程,或提供数据的进程)调用唤醒原语(Wakeup),将等待该事件的进程唤醒。唤醒原语的执行过程如下:
- 在该事件的等待队列中找到相应进程的PCB。
- 将其从等待队列中移出,并置其状态为就绪态。
- 将该PCB插入就绪队列,等待调度程序调度。
1.1.7进程间通信
进程通信是指进程之间的信息交换。高级通信方式是指以较高的效率传输大量数据的通信方式。高级通信方法主要有以下三类:
1.1.7.1共享存储
在通信的进程之间存在一块可直接访问的共享空间,通过对这片共享空间进行写/读操作实现进程之间的信息交换。
共享存储又分为两种:低级方式的共享是基于数据结构的共享;高级方式的共享则是基于存储区的共享。
基于数据结构的共享:比如共享空间里只能放一个长度为10的数组。这种共享方式速度慢、限制多,是一种低级通信方式。
基于存储区的共享:操作系统在内存中划出一块共享存储区,数据的形式、存放位置都由通信进程控制,而不是操作系统,操作系统只负责为通信进程提供可共享使用的存储空间和同步互斥工具。这种共享方式速度最快,是一种高级通信方式。
1.1.7.2消息传递
进程间的数据交换以格式化的消息(Message)为单位。进程通过操作系统提供的“发送消息/接收消息”两个原语进行数据交换,这种方式隐藏了实现细节,使通信过程对用户透明,简化了通讯程序的设计,是当前应用最广泛的进程间通信机制。
消息传递又分为两种:直接通信方式与间接(信箱)通信方式
直接通信方式:发送进程直接将消息发送给接收进程,并将它挂在接收进程的消息缓冲队列上,接收进程从消息缓冲队列中取得消息。
间接(信箱)通信方式:发送进程将消息发送到某个中间实体,接收进程从中间实体取得消息。这种中间实体一般称为信箱。可以多个进程往同一个信箱send消息,也可以多个进程从同一个信箱中receive消息。该通信方式广泛应用于计算机网络。
1.1.7.3管道通信
管道是一个特殊的共享文件,又称pipe文件,其实就是一个在内存中开辟的大小固定的内存缓冲区
进程通过管道进行通信遵循下列规则:
- 管道在某一时间段内只能实现单向传输。如果要实现双向同时通信,则需要设置两个管道
- 各进程要互斥地访问管道(由操作系统实现)
- 当管道写满时,写进程将阻塞,直到读进程将管道中的数据取走,即可唤醒写进程
- 当管道读空时,读进程将阻塞,直到写进程往管道中写入数据,即可唤醒读进程
- 管道中的数据一旦被读出,就彻底消失。因此,当多个进程读同一个管道时,可能会错乱。对此,通常有两种解决方案:一个管道允许多个写进程,一个读进程(2014年408真题高教社官方答案);允许有多个写进程,多个读进程,但系统会让各个读进程轮流从管道中读数据(Linux的方案)
1.2线程
1.2.1线程的概念
有的进程可能需要“同时”做很多事,而传统的进程只能串行地执行一系列程序。为此,引入了“线程”,来增加并发度。
可以把线程理解为“轻量级进程”,线程是一个基本的CPU执行单元, 也是程序执行流的最小单位。
线程控制块TCB:用于记录控制和管理线程的信息。线程控制块通常包括:①线程标识符;②一组寄存器,包括程序计数器、状态寄存器和通用寄存器;③线程运行状态,用于描述线程正处于何种状态;④优先级;⑤线程专有存储区,线程切换时用于保存现场等;⑥堆栈指针,用于过程调用时保存局部变量及返回地址等。
引入线程带来的变化:
1.2.2线程的属性
1.2.3线程的实现方式
1.2.3.1用户级线程
用户级线程就是“从用户视角能看到的用户态的线程”
1.用户级线程由应用程序通过线程库实现,所有的线程管理工作都由应用程序负责(包括线程切换)
2.用户级线程中,线程切换可以在用户态下即可完成,无需操作系统干预。
3.在用户看来,是有多个线程。但是在操作系统内核看来,并意识不到线程的存在。
- 优点:用户级线程的切换在用户空间即可完成,不需要切换到核心态,线程管理的系统开销小,效率高。
- 缺点:当一个用户级线程被阻塞后,整个进程都会被阻塞,并发度不高。多个线程不可在多核处理机上并行运行。
1.2.3.2内核级线程
“内核级线程”就是“从操作系统内核视角看能看到的线程”
1. 内核级线程的管理工作由操作系统内核完成。
2. 线程调度、切换等工作都由内核负责,因此内核级线程的切换必然需要在核心态下才能完成。
3.操作系统会为每个内核级线程建立相应的TCB(Thread Control Block,线程控制块), 通过TCB对线程进行管理。
- 优点:当一个线程被阻塞后,别的线程还可以继续执行,并发能力强。多线程可在多核操作处理机上并行执行。
- 缺点:一个用户进程会占用多个内核级线程,线程切换由操作系统内核完成,需要切换到核心态,因此线程管理的成本高,开销大。
用户级线程是“代码逻辑”的载体
内核级线程是“运行机会”的载体
1.2.4多线程模型
1.2.4.1多对一模型
多个用户级线程映射到一个内核级线程。一个进程只被分配一个内核级线程。
1.2.4.2一对一模型
一个用户级线程映射到一个内核级线程。一个进程被分配与用户级线程同数量的内核级线程。
1.2.4.3多对多模型
n用户及线程映射到m个内核级线程(n >= m)。
总结