【操作系统】二、进程管理:1.进程与线程(程序、进程(PCB、状态转换、原语、进程间通信)、线程(多线程模型))

二、进程与线程


程序静态的。一个指令序,就是个存放在磁盘里的可执行文件,就是一系列的指令集合。

进程动态的。程序的一次执行过,同一个程序多次执行,也会有多个进程。

1.程序

1.1顺序执行的特征

  1. 顺序性
  2. 封闭性
  3. 可再现性

1.2并发执行的特征

  1. 间断性
  2. 失去封闭性
  3. 不可再现性

在这里插入图片描述

2.进程Process

2.1定义(组织)

为了使程序可以并发执行,并且可以对并发的程序进行描述和控制。

当进程被创建,操作系统会为该进程分配一个唯一的、不重复的“身份证号”PID(Process ID,进程ID)。

3个定义:

  1. 进程是程序的依次执行。

  2. 进程是一个程序及其数据在处理机上的顺序执行时发生的活动

    **【注意】**并发进程的运行结果具有不可再现性(每次都不一样)。

  3. 进程是具有独立功能的程序在一个数据集上的执行过程,它是系统进行资源分配和调度的一个独立的单位

进程是动态的;
进程实体(进程映像)是静态的。

一个进程实体进程映像)由PCB程序段数据段组成。进程实体反应了进程在某一时刻的状态。进程实体可以看作进程在某一时刻的快照。

进程是进程实体的运行过程,是系统进行资源分配调度的一个独立单位。

PCB是给操作系统用的。程序段、数据段是给进程自己用的,与进程自身的运行逻辑有关。

2.1.1程序段

程序的代码,静态的(指令序列)。

2.1.2数据段

运行过程中产生的各种数据(如:程序中定义的变量)

2.1.3进程控制块PCB

process control block,PCB

创建进程实质上就是创建PCB,撤销进程就是撤销PCB。它是进程存在的唯一标志

1)内容
  1. 进程描述

    基本的进程描述信息,可以让操作系统区分各个进程。

    • 进程标识符PID
    • 用户标识符UID
  2. 进程调度(资源分配)信息

    给进程分配了哪些资源,可用于实现操作系统对资源的管理。

    • 在使用哪些内存区域(分配了多少内存)
    • 正在使用哪些I/O设备
    • 正在使用哪些文件
    • 代码段、数据段、堆栈段指针
    • 文件描述符
  3. 进程控制和管理信息

    • 进程当前状态

      • 就绪态
      • 阻塞态
      • 稳定态
    • 进程优先级

    • 代码运行入口地址

    • 程序外存地址

    • 进入内存时间

    • CPU、磁盘、网络使用情况

    • 信号量使用

  4. 处理机状态

    进程的运行情况,可用于实现操作系统对进程的控制、调度、进程切换。

    • 通用寄存器、地址寄存器、控制寄存器PC、标志寄存器PSW
    • 状态字

可以查看Linux源码中的task struct:Linux的进程控制块。

2)作用

使一个在多道程序环境下不能独立运行的程序(含数据),成为一个能够独立运行的基本单位,即一个能与其他进程并发执行的进程。

3)进程组织方式
  • 线性
  • 链接
  • 索引

在这里插入图片描述

为什么OS引入进程的概念?

为了使程序可以并发执行,并且可以对并发的程序进行描述和控制。

2.2特征

  1. 动态性:(进程基本特征)
    • 进程是程序的一次执行过程,是动态地产生、变化和消亡的。
  2. 并发性:
    • 内存中有多个进程实体,各进程可并发执行。
  3. 独立性:
    • 进程是能独立运行、独立获得资源、独立接受调度的基本单位。
  4. 异步性
    • 各进程按各自独立的、不可预知的速度向前推进,会导致并发程序执行结果的不确定性。操作系统要提供"进程同步机制"来解决异步问题。
  5. 结构性:
    • 每个进程都会配置一个PCB。结构上看,进程由程序段、数据段、PCB组成。

2.3进程的状态与转换

3种基本状态:

  • 就绪态(ready)- 就绪队列。

  • 执行态(running,运行态):单核的活就只能同时有一个在执行。

  • 阻塞态(blocked/waiting,等待态)- 阻塞队列。

    阻塞态是进程为了I/O或其他资源主动发起的。

加入创建终止:

  • 创建态(new,新建态):分配资源、初始化PCB。
  • 终止态(terminated,结束态):一个进程可以执行exit系统调用,请求操作系统终止该进程。此时该进程会进入“终止态”,OS会让该进程下CPU,并回收内存空间、PCB等资源。终止工作完成进程彻底消失。

在这里插入图片描述

2.3.1挂起(7状态模型)

挂起:将内存中的进程放入外存。

  • 挂起原语suspend

  • 激活原语active

在这里插入图片描述

加入创建终止:

在这里插入图片描述

2.4进程控制

进程控制的主要功能是对系统中的所有进程实施有效的管理,它具有创建新进程、撤销已有进程、实现进程状态转换等功能。

【简化理解】进程控制就是要实现进程状态转换。

  • 如何实现进程控制?

使用“原语”实现。

原语

原语具有原子性,在执行期间不允许中断,一气呵成。采用关中断开中断这两个特权指令实现原子性。

2.4.1创建

创建步骤(创建原语):

  1. 申请空白PCB;
  2. 申请资源。运行所需要的物理、逻辑资源;
  3. 初始化PCB。把资源分配给PCB;
  4. 如果进程就绪队列能够接纳新进程,就把新进程插入就绪队列。

引起创建的事件:

  1. 用户登录:分时系统中,用户登录成功,系统会建立为其建立一个新的进程。

  2. 作业调度:多道批处理系统中,有新的作业放入内存时,会为其建立一个新的进程。

  3. 提供服务:用户向操作系统提出某些请求时,会新建一个进程处理该请求。

  4. 应用请求:由用户进程主动请求创建一个子进程。

2.4.2终止

终止过程(撤销原语):

  1. 根据被终止进程的标识符PID,从PCB集合中检索出该进程的PCB,从该进程PCB中读出该进程的状态;
  2. 若进程是running,则立即终止进程执行。调度标志为真,指示该进程被终止后应该重新调度;
  3. 若有子进程,应终止所有子进程,防止它们变成不可控进程;
  4. 被终止的进程拥有的所有资源,全部归还给父进程或者系统;
  5. 将被终止的进程的PCB从队列或链表中移除。

引起终止的事件:

  1. 正常结束:进程自己请求终止(exit系统调用)。
  2. 异常结束:整数除以0、非法使用特权指令,然后被操作系统强行杀掉。
  3. 外界干预:Ctrl+Alt+delete,用户选择杀掉进程。
2.4.3阻塞、唤醒

阻塞、唤醒就是一正一反,必须成对使用。

阻塞原语:

  1. 找到要阻塞的进程对应的PCB;
  2. 保护进程运行现场,将PCB状态信息设置为“阻塞态",暂时停止进程运行;
  3. 将PCB插入相应事件的等待队列。

唤醒原语:

  1. 在事件等待队列中找到PCB;

  2. 将PCB从等待队列移除,设置进程为就绪态;

  3. 将PCB插入就绪队列,等待被调度。

引起的事件:

  1. 向系统请求共享资源失败
  2. 等待某种操作的完成
  3. 等待新数据到达
  4. 等待新任务到达
2.4.4切换

把运行态的进程进行切换。

切换原语:

  1. 运行环境(寄存器存放的内容环境)信息存入PCB1;
  2. PCB1移入相应队列;
  3. 选择另一个进程执行,并更新其PCB2;
  4. 根据PCB2恢复新进程所需的运行环境

引起的事件:

  1. 当前进程时间片到
  2. 有更高优先级的进程到达
  3. 当前进程主动阻塞
  4. 当前进程终止

2.5进程间通信IPC

进程间通信(Inter-Process Communication,IPC)是指两个进程之间产生数据交互。进程之间的信息交换(通信),通常有低级、高级之分。

一个进程不被允许直接访问其他进程的地址空间

2.5.1共享存储器

shared-memory system

两个进程有一个共享空间。两者对其的访问是互斥的(如PV操作)。

注:通过“增加页表项/段表项”即可将同一片共享内存区映射到各个进程的地址空间中(第三章内容)。

在这里插入图片描述

  • 基于数据结构共享

    比如共享空间里只能放一个长度为10的数组。这种共享方式速度慢、限制多,是一种低级通信方式

    • 低级通信

    • 在这个空间只能固定存储一种数据结构,速度慢。

  • 基于存储区共享

    操作系统在内存中划出一块共享存储区,数据的形式、存放位置都由通信进程控制,而不是操作系统。这种共享方式速度很快,是一种高级通信方式。

    • 高级通信
    • 存储更自由,速度更快。
2.5.2管道通信

管道”是一个特殊的共享文件,又名pipe文件。其实就是在内存中开辟一个大小固定的内存缓冲区。

  • 管道只能采用半双工通信,某一时间段内只能实现单向的传输。如果要实现双向同时通信,则需要设置两个管道
  • 各进程要互斥地访问管道。
  • 数据以字符流的形式写入管道,
    • 当管道写满时,写进程的write()系统调用将被阻塞,等待读进程将数据取走。
    • 当读进程将数据全部取走后,管道变空,此时读进程的read()系统调用将被阻塞。
  • 管道中的数据一旦被读出,就彻底消失。因此,当多个进程读同一个管道时,可能会错乱。对此,通常有两种解决方案:
    1. 一个管道允许多个写进程,一个读进程(2014年408真题高教社官方答案);
    2. 允许有多个写进程,多个读进程,但系统会让各个读进程轮流从管道中读数据(Linux的方案)。

【注意】只要没满,就可以写;只要没空,就可以读。

在这里插入图片描述

2.5.3消息传递

进程间的数据交换以格式化的消息(Message)为单位。进程通过操作系统提供的“发送消息send / 接收消息receive”两个原语进行数据交换。

  • 直接通信方式

    发送进程利用OS所提供的发送原语,直接把消息发送给目标进程。

  • 间接通信方式

    发送进程、接收进程都通过共享中间体(信箱)的方式进行消息的发送、接收,完成进程间通信。

3.线程thread

线程(thread)是操作系统能够进行运算调度的最小单位。用于处理相同程序的不同片段的并发执行。

它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。

在Unix System V及SunOS中也被称为轻量进程(lightweight processes),但轻量进程更多指内核线程(kernel thread),而把用户线程(user thread)称为线程。

父进程可以打开子进程或者线程,使用线程共享的数据更多,占用空间更小

【注意】线程没有自己独立的地址空间,它共享其所属的进程的空间。

在这里插入图片描述

引入线程之后变化:

  • 资源分配、调度
    • 传统进程机制,进程是资源分配、调度的基本单位。
    • 引入线程之后,线程是资源分配、调度的基本单位,线程成为了一个基本的CPU执行单元,程序执行流的最小单位进程成为了除CPU外系统资源的分配单元(如打印机、内存地址空间等都是分配给进程的)。
  • 并发性
    • 传统进程机制,只能进程间并发。
    • 引入线程之后,各线程间也能并发,提升了系统并发度
  • 系统开销
    • 传统的进程间并发,需要切换进程的运行环境,系统开销很大。
    • 引入线程之后,线程间并发,如果是同一进程内的线程切换,则不需要切换进程环境,系统开销小。

  • 线程的属性:
  1. 线程是处理机调度的单位
  2. 多CPU计算机中,各个线程可占用不同的CPU
  3. 每个线程都有一个线程ID、线程控制块(TCB)
  4. 线程也有就绪、阻塞、运行三种基本状态
  5. 线程几乎不拥有系统资源
  6. 同一进程的不同线程间共享进程的资源
  7. 由于共享内存地址空间,同一进程中的线程间通信甚至无需系统干预
  8. 同一进程中的线程切换,不会引起进程切换
  9. 不同进程中的线程切换,会引起进程切换
  10. 切换同进程内的线程,系统开销很小
  11. 切换进程,系统开销较大

3.1组织与控制

线程的组织和进程一样。进程有进程控制块PCB,线程有线程控制块TCB,thread control block)。

3.1.1线程控制块TCB

包含的内容:

其中程序计数器PC、其他寄存器、堆栈指针是线程切换时要保存/恢复。

  1. 线程标识符:TID,与PID类似
  2. 程序计数器PC:线程目前执行到哪里
  3. 其他寄存器:线程运行的中间结果
  4. 堆栈指针:堆栈保存函数调用信息、局部变量等
  5. 线程运行状态:运行/就绪/阻塞
  6. 优先级:线程调度、资源分配的参考

多个TCB(线程)组织成一张线程表(thread table),构成进程。


控制就是不同线程间的状态转换,也是就绪态、运行态、阻塞态之间的转换,和进程一样。

3.2实现方式

3.2.1用户级线程ULT

用户级线程(User-Level thread,ULT)

历史背景:早期的操作系统(如:早期Unix)只支持进程,不支持线程。当时的“线程”是由线程库实现的。

用户可以看到的线程。

在这里插入图片描述

  • 线程的管理工作由谁来完成?

应用程序通过线程库完成,不是操作系统。

  • 线程切换是否需要CPU变态(用户态→内核态)?

不需要。因为应用程序是在用户态的,没有涉及内核态的操作系统。

  • 操作系统是否能意识到用户级线程的存在?

不能。

  • 优点:用户级线程的切换在用户空间即可完成,不需要切换到核心态,线程管理的系统开销小,效率高
  • 缺点:当一个用户级线程被阻塞后,整个进程都会被阻塞,并发度不高。多个线程不可在多核处理机上并行运行。
3.2.2内核级线程KLT

内核级线程(Kernel-Level thread,KLT)也叫内核级支持线程(kernel supported thread,KST)

如现在的Windows、Linux。

在核心态完成,内核级线程才是处理机分配的单位(多线程情况下也是)。

在这里插入图片描述

  • 优点:当一个线程被阻塞后,别的线程还可以继续执行,并发能力强。多线程可在多核处理机上并行执行。
  • 缺点:一个用户进程会占用多个内核级线程,线程切换由操作系统内核完成,需要切换到核心态,因此线程管理的成本高,开销大,效率低

在支持内核级线程的系统中,根据用户级线程和内核级线程的映射关系(将ULT和KLT结合),可以划分为几种多线程模型

3.3多线程模型

  • 多对一

多个ULT映射到1个KLT中,但看一个KLT就是普通的ULT

  1. 系统开销小,效率高。ULT的切换只需要在用户空间就可以实现,不需要切换到核心态。

  2. 并发度不高。一个ULT阻塞,整个KLT也会被阻塞。

  • 一对一

变成了纯粹的内核级线程

  1. 线程管理成本高,开销大。一个用户进程会占用一个KLT,每次都要切换到操作系统内核完成。
  2. 并发性高。
  • 多对多

克服了并发度不高,解决了开销太大。

有3个用户级线程,映射到了2个内核级线程(KLT),那么就是2个线程单位,4核处理机最多分配它2核。

  • 21
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值