[What]计算机操作系统_进程管理

在传统的操作系统中,程序并不能独立运行,作为资源分配和独立运行的基本单位都是进程。

进程的基本概念

程序的顺序执行及其特征

程序个各个部分都是按照先后顺序来执行的,具有以下特征:

  1. 顺序性
  2. 封闭性:程序运行时独占全机资源,一旦开始运行,其执行结果不受外界因素影响
  3. 可再现性:只要程序环境和初始条件一致,当程序执行时的结果都相同。

前趋图

前趋图(Precedence Graph)是一个 有向无循环图(DAG, Directed Acyclic Graph) ,用于描述进程之间的前后关系。

  • 没有前趋的结点称为初始结点(Initial Node)
  • 没有后继结点的称为终止结点(Final Node)
  • 每个结点还具有一个重量(Weight),用于表示该结点所含有的程序量或结点的执行时间。

注意:前趋图不能有循环!

程序的并发执行及其特征

程序的并发执行

根据程序的执行流程,提取出流程之间相互不依赖的过程,并将它们调整为并发执行的状态。

程序并发执行时的特征

提高了系统吞吐量但也产生了一些与程序顺序执行时不同的特征:

  • 间断性:流程之间的并发需要做同步,一些流程可能会等待其他流程,就会具有“执行–暂停–执行”的间断性活动
  • 失去封闭性:多个流程访问统一资源时的互斥导致这些资源的状态将由多个程序来改变,致使程序的运行失去了封闭性
  • 不可再现性:流程的运行时间不好把握,导致运行流程不容易再现

进程的特征与状态

进程的特征和定义

为了使程序能并发执行,且为了对并发执行的程序加以描述和控制,引入了 进程 的概念。

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

进程具有以下特征:

  • 结构特征:进程控制块PCB(Process Control Blcok)、程序段、相关数据段构成了进程实体。
  • 动态性:进程有一定的生命期,而程序只是一组有序指令的集合,并存放于介质上,是静态的。
  • 并发性:多个进程同存于内存中,且能在一段时间内同时运行。
  • 独立性:进程实体是一个能独立运行、独立分配资源和独立接受调度的基本单位。
    • 未建立PCB的程序都不能作为一个独立的单位参与运行
  • 异步性:进程按各自独立的、不可预知的速度向前推进。

进程的三种基本状态

运行中的进程可能具有以下三种基本状态:

  • 就绪(Ready)状态:当进程已分配到除CPU以外的所有必要资源后,只要再获得CPU便可立即执行的状态。
    • 就绪状态的进程可能有多个,通常置于队列中,称为就绪队列。
  • 执行状态:进程已经获得CPU并正在执行。
    • 单核系统中,只有一个进程处于执行状态。多核则有多个。
  • 阻塞状态:正在执行的进程由于发生某事件和暂时无法继续执行时,便放弃处理器而处于暂停状态
    • 致使进程阻塞的典型事件有:请求I/O,申请缓冲空间等。
    • 系统会将阻塞进程放入阻塞队列

挂起状态

引入挂起状态的原因:

  • 终端用户请求:终端用户在自己的程序运行期间发现有可疑问题时,希望使正在执行的进程暂停。

若此时进程处于就绪态,则该进程暂不接收调度,以便用户研究其执行情况或对程序进行修改。这种静止的状态就称为挂起状态。

  • 父进程请求:有时父进程希望挂起自己的某个子进程,以便考查和修改子进程或者协调各子进程间的活动。
  • 负荷调节的需要:系统工作负荷较重时已可能影响到实时任务的控制时,系统把不重要的进程挂起。
  • 操作系统的需要:操作系统有时希望挂起某些进程,以便检查运行中的资源使用情况或进程记账。

创建状态和终止状态

  • 创建状态:当一个新进程被创建时,系统已为其分配了PCB,填写了进程标识等信息,但由于该进程所必需的资源或其他信息尚未分配,

进程自身还未进入主存,还不能被调度执行,其所处的状态就是创建状态。

  • 终止状态:在等待操作系统进行善后处理并清零其PCB,将PCB空间返还给系统,进程便被终止。
    • 进入终止态的进程在操作系统中依然保留一个记录,其中保持状态码和一些统计数据供其他进程收集,

一旦其它进程完成了对终止状态进程信息提取后,系统将删除该进程。

状态图

process_status.jpg

进程控制块

进程控制块的作用

PCB(Process Control Block)中记录了操作系统所需的、用于描述进程的当前情况以及控制进程运行的全部信息。 PCB 是进程存在的唯一标志。

  • PCB需要被经常调用,故PCB常驻内存。
  • 系统将所有的PCB组织成若干个链表(或队列),存放在操作系统中专门开辟的PCB区内

进程控制块中的信息

  • 进程标识符:用于标识唯一个进程
    • 内部标识符:一个数字标识符,为了方便系统使用
    • 外部标识符:由字母和数字组成,方便用户使用
  • 处理器状态:主要是寄存器信息
    • 通用寄存器:通用信息
    • 指令计数器:下一条指令访问的地址
    • 程序状态字PSW:含有状态信息
    • 用户栈指针:栈用于存放过程和系统调用参数即地址,栈指针指向栈顶
  • 进程调度信息
    • 进程状态
    • 进程优先级
    • 进程调度所需的其他信息
    • 事件:进程由执行状态转变为阻塞状态所等待发生的事件
  • 进程控制信息
    • 程序和数据地址
    • 进程同步和通信机制
    • 资源清单:除CPU以外的进程所需要的全部资源以及已经分配到该进程的资源
    • 链接指针:本进程所在队列中的下一个进程的PCB首地址

进程控制块的组织方式

  • 链接方式:把具有同一状态的PCB链接成一个队列
  • 索引方式:系统根据所有进程的状态建立几张索引表

进程控制

进程控制一般是由原子操作来完成的,避免被打断。

进程的创建

子进程可以继承父进程的所有资源,当子进程被撤销时,应将其从父进程那里获得的资源归还给父进程。 在撤销父进程时,也必须同时撤销其所有的子进程。

引起创建进程的事件

系统中运行的最基本单位就是进程,所以为了使程序能够运行,就必须为它创建进程。

  • 用户登录
  • 作业调度:在批处理系统中,调度到某作业时,便为作业分配资源并创建进程
  • 提供服务:当运行中的用户程序提出某种请求后,系统将专门创建一个进程来提供用户所需要的服务。
  • 应用请求:应用程序自己创建进程以并发的方式运行

创建进程的步骤

  • 申请空白的PCB:获得唯一的数字标识
  • 为新进程分配资源
  • 初始化进程控制块
    • 初始化标识信息
    • 初始化处理机状态
    • 初始化处理机控制信息
  • 将新进程插入就绪队列

进程的终止

引起进程终止的事件

  • 正常结束
  • 异常结束
    • 越界:访问存储区越界
    • 保护:不具备访问资源的权限
    • 非法指令:执行一条不存在的指令
    • 特权指令:用户进程视图执行一条只允许OS执行的指令
    • 运行超时:进程的执行时间超过了指定的最大值
    • 等待超时:进程等待某时间的时间超过了规定的最大值
    • 运算错误:进程视图执行一个被禁止的运算,比如除0错误
    • I/O故障:I/O过程发生了错误
  • 外界干预
    • 用户或操作系统干预
    • 父进程请求:父进程可以请求终止子进程
    • 父进程终止:父进程退出时,其子孙进程也会终止

进程的终止过程

  • 根据被终止进程的标识符,从PCB集合中索引出该进程,从中读出该进程的状态
  • 若被终止进程正处于执行状态,应立即终止该进程的执行,并置调度标志为真,用于指示该进程被终止后应重新进行调度
  • 若该进程还有子孙进程,应将其所有的子孙进程予以终止,以防它们成为不可控的进程
  • 将被终止进程所拥有的全部资源归还给父进程或系统
  • 将被终止进程的PCB从队列(或链表)中移出,等待其他程序来搜集信息

进程的阻塞与唤醒

引起进程阻塞和唤醒的事件

  • 请求系统服务
  • 启动某种操作:进程等待该操作完成再继续执行
  • 新数据尚未到达:等待另外一个进程产生的数据
  • 无新工作可做

进程阻塞的过程

  • 停止执行,把PCB中的状态改为阻塞,并将PCB插入到阻塞队列。
  • 转调度程序进行重新调度,将处理器分配给另一个就绪进程并切换

进程唤醒过程

  • 把被阻塞的进程从等待该事件的阻塞队列中移出
  • 将PCB中的状态改为就绪,并将该PCB插入就绪队列中

进程的挂起与激活

进程的挂起

  • 检查被挂起进程的状态,将活动就绪态改为静止就绪,将活动阻塞态改为静止阻塞
  • 把该进程的PCB复制到某指定内存区域
  • 重新调度

进程激活的过程

  • 将外存上处于静止就绪状态的该进程换入内存
  • 修改进程状态为活动就绪或活动阻塞
  • 检查进程优先级以决定是否同步

进程同步

进程同步的主要任务:对多个相关进程在执行次序上进行协调,以使并发执行的诸进程之间能有效地共享资源和相互合作, 从而使程序的执行具有可再现性。

进程同步的基本概念

两种形式的制约关系

  • 间接相互制约关系:进程要等待占用该资源的进程释放该资源后再继续进入就绪态
  • 直接相互制约关系:进程间的相互合作,主动唤醒对方(生产者和消费者)

临界资源(Critical Resource)

诸进程间采取互斥的方式实现临界资源的共享。

临界区(critical section)

人们把在每个进程中访问临界资源的那段代码称为临界区。

临界区的访问需要互斥:

  • 在进入临界区进行检查的代码称为进入区(entry section)
  • 在退出临界区进行释放的代码称为退出区(exit section)

同步进制应遵循的规则

  • 空闲让进:当无进程处于临界区时,应允许一个请求的进程进入临界区
  • 忙则等待:当已有进程进入临界区时,应让其他请求的进程等待
  • 有限等待:对要访问临界资源的进程,应保证有限时间内能进入自己的临界区,以免死等
  • 让权等待:当进程不能进入临界区时,应立即释放处理器资源避免忙等。

信号量(semaphores)

整型信号量

整型信号量定义为一个用于表示资源数目的整型量S,除初始化外,仅能通过两个标准的原子操作 wait(S) 和 signal(S) 来访问。

记录型信号量

整型信号量并未遵循"让权等待",而是使进程处于"忙等"的状态。记录型信号量机制则是一种不存在“忙等”现象的进程同步机制。

记录型信号量除了包含代表资源数目的整型变量外,还具有一个等待该信号量的进程链表。

AND型信号量

AND同步机制用于进程需要先获得两个或更多的共享资源后才能执行的环境。

其基本思想是:将进程在整个运行过程中需要的所有资源,一次性全部地分配给进程,待进程使用完后在一起释放。

信号量集

对AND信号量进行扩充,可以一次性获得n个相同的信号量。

信号量的应用

利用信号量实现进程互斥

在这种情况下,wait(mutex)和signal(mutex)必须成对地出现。

利用信号量实现前趋关系

在一个进程中释放信号量,在另外一个进程中等待信号量,这样便能使能运行关系可控。

管程机制

信号量的大量使用,将导致管理这些信号逻辑不那么方便同时也可能造成死锁。

在解决这个问题的过程中,便产生了新的同步工具–管程(Monitors).

管程的定义

利用共享数据结构抽象地表示系统中的共享资源,而把对该共享数据结构的实施操作定义为一组过程。 进程对共享资源的申请、释放和其他操作,都是通过这组过程对共享数据结构的操作来实现的,这组过程还可以根据 资源的情况,或接受或阻塞进程的访问,确保每次仅有一个进程使用共享资源,这样就可以以统一管理对共享资源的所有访问,实现进程互斥。

也就是说,使用面向对象的思想。将各个进程要使用的资源抽象为对应的数据和方法,各个进程的申请都需要通过统一的方法来访问,
这样就达到了使用一组方法管理这些资源的目的。而不是让很多信号量散落在各地。

代表共享资源的数据结构,以及由对该共享数据结构实施操作的一组过程所组成的资源管理程序,共同构成了一个操作系统的资源管理模块, 称之为管程。

管程的组成部分:

  • 管程的名称
  • 局部于管程内部的共享数据结构说明
  • 对局部于管程内部的共享数据设置初始值的语句
  • 对该数据结构进行操作的一组过程

注意:局部于管程内部的数据结构仅能被局部于管程内部的过程所访问。反之,局部于管程内部的过程也仅能访问管程内的数据结构。

从语言的角度看,管程主要有一下特性:

  • 模块化:管程是一个基本程序单位,可以单独编译
  • 抽象数据类型
  • 信息掩蔽

管程与进程不同,主要提现在以下几个方面:

  • 进程定义的是私有数据结构PCB,管程定义的是公共数据结构
  • 进程是顺序执行有关数据操作,管程主要是进行同步操作和初始化操作
  • 进程的目的在于实现系统的并发性,管程的设置则是解决共享资源的互斥使用问题
  • 进程是主动处理数据,管程是被动工作方式
  • 进程之间能并发执行,而管程则不能与其调用者并发
  • 进程具有动态性,可以被创建和消亡,而管程则是操作系统中的一个资源管理模块

条件变量

通常一个进程被阻塞或挂起的条件有多个,使用条件变量来标明这些条件。

如果进程之间的需要条件不重叠,则可以并发使用管程。

经典进程的同步问题

生产者–消费者问题

利用记录型信号量解决生产者–消费者问题

处理这种问题需要以下两种信号量:

  • 记录型信号量个数代表了有效资源的个数
  • 互斥型信号量为了保护资源索引的值不被意外修改
product_consumer.jpg

利用AND信号量解决生产者–消费者问题

利用AND信号量将获取和等待计数值和互斥操作合并为一个操作

利用管程解决生产者–消费者问题

通过向管程发送消息的方式来处理这个问题就变得很简单了。

哲学家进餐问题

有5个哲学家共用一张圆桌,分别坐在周围的5张椅子上,在圆桌上有5个碗和5只筷子,他们的生活方式是交替地进行思考和进餐。
平时一个哲学家进行思考,饥饿时便试图取用其左右最靠近他的筷子,只有在他拿到两只筷子时才能进餐,进餐完毕,放下筷子继续思考。

利用记录型信号量解决

  • 将一只筷子表示为一个信号量,一共有5个信号量,并且每个的初值为1.
  • 每个进程都要先拿到 i 和 (i + 1) / 5 两个信号量后才能够获得资源使用权

问题:当5个进程都试图先拿 i 信号量在拿 (i + 1)/5 信号量时,那么第二个信号量将由于获取失败而导致进程死锁。

有以下几种方法解决:

  1. 最多允许4为哲学家拿 i 信号量,这样能保证至少有1个进程可以获得资源
  2. 预先判断 i 和 (i + 1)/5 均可用时才获取信号量
  3. 奇数号进程先拿 i 再拿 (i + 1)/5 ,偶数号进程则相反

利用AND信号量解决

AND信号量则一次同时获得两个信号量,就没有上述问题。

读者–写者问题

允许多个进程同时读一个共享对象,因为读不会使数据操作混乱。 但不允许一个写进程和其他的读或写进程同时操作一个对象,这会照成数据操作混乱。

利用记录型信号量解决

read_write.jpg

利用信号量集机制解决

信号量集可以使得操作更为简便

进程通信

信号量作为同步工具是有效的,但是作为通信工具则有以下缺点:

  1. 效率低:生产者和消费者每次只能向缓冲池写或读一个消息
  2. 通信对用户不透明:用户需要考虑之间的互斥等问题

进程通信的类型

共享内存(Shared-Memory System)

进程共享存储区的方式来通信,具有以下两种类型:

  • 基于共享数据结构的通信方式
    • 公用的数据结构和进程的同步处理都是由程序员来完成的,所有仅适用于少量数据
  • 基于共享存储区的通信方式
    • 共用申请的一片内存,用户直接操作内存即可,适用于大量数据。

消息传递(Message passing system)

消息传递机制以消息的方式交互数据,也能传送大数据,应用广泛。

管道通信

所谓“管道”,是指用于连接一个读进程和一个写进程以实现它们之间通信的一个共享文件,又名pipe文件,使用于大量数据传输。

管道机制提供以下三方面的协调能力:

  1. 互斥:当一个进程执行读/写时,另一个进程必须等待
  2. 同步:当写进程写入一定数量数据后便等待读进程,读进程读完后再唤醒写进程。反之同理
  3. 确定对方是否存在,只有确定存在时才能进行通信。

消息传递通信的实现方法

直接通信方式

发送进程直接把消息发送给目标进程,此时需要双方进程都提供对方标识符。

Send(Receiver, message);
Receive(Sender, message);

间接通信方式

进程之间的通信需要通过作为共享数据结构的实体通信,该实体暂存消息。

实例通常称为信箱,信箱既可以实现实时通信,又可以实现非实时通信。

信箱的操作有:

  1. 信箱的创建和撤销
  2. 消息的发送和接收
Send(mailbox, message);
Receive(mailbox, message);

信箱的类型有:

  1. 私用信箱:信箱拥有者有权读取消息,其他用户只能发送消息
  2. 共用信箱:由系统创建,即可发送也可接收
  3. 共享信箱:创建时指定共享的进程,拥有者和共享者都可以读写信箱

使用信箱通信的进程关系:

  1. 一对一关系
  2. 多对一关系:客户/服务端交互
  3. 一对多关系:广播方式
  4. 多对多关系:多个进程相互共享

消息传递系统实现中的若干问题

通信链路(communication link)

有两种方式建立通信链路:

  1. 发送进程在通信前用显示的“建立链接”命令建立链路,使用完后显示拆除,主要用于计算机网络中
  2. 发送进程利用系统发送命令,系统自动建立链路,主要用于单机

通信链路分为两类链接方式:

  1. 点对点链接
  2. 多点链接

通信链路分为两类通信方式:

  1. 单向通信
  2. 双向通信

通信链接按容量分为:

  1. 无容量链路:没有缓存
  2. 有容量链路

消息格式

  • 单机环境下消息格式比较简单,但在计算机网络下消息格式就要复杂得多。
  • 消息可以有定长消息格式,便于处理。和变长消息格式,便于用户操作。

进程同步方式

  • 发送和接收进程都阻塞:用于进程紧密同步(tight synchronization),这种同步方式称为汇合(rendezrous)
  • 发送不阻塞,接收阻塞:通常用于C/S架构,服务器发送消息后唤醒对应的接收进程
  • 发送和接收进程都不阻塞:发送和接收之间具有缓冲区二者可以同时工作

消息缓冲队列通信机制

线程

线程的基本概念

  • 由于进程是一个资源的拥有者,因而在创建、撤销和切换中,系统必须为此付出较大的时空开销。
    • 系统中所设置的进程数量不宜过多,进程切换频率也不宜过高

进程与线程的比较

  • 调度:在引入线程前,进程是基本调度单位。引入线程后,则把线程作为调度的和分派的基本单位,而进程作为资源拥有的基本单位。
    • 这样同一进程中的线程切换不会引起进程的资源切换而提高性能
  • 并发性:一个进程中的多个线程并发的运行能更多的提高系统资源的利用率和系统吞吐量。
    • 当一个线程被阻塞还有其他线程可以切换运行
  • 拥有资源:同一进程中的所有线程可以共享该进程的资源。
  • 系统开销:线程控制块占用量小切换高效,且线程之间的同步和通信都无需系统内核干预,更进一步提高了其效率。

线程的属性

  • 轻量实体:线程控制块(TCB),用于指示被执行指令序列的程序计数器,保留局部变量、少数状态参数和返回地址等的一组寄存器和堆栈
  • 独立调度和分派的基本单位
  • 可并发执行
  • 共享进程资源

线程的状态

  • 状态参数:在系统中的每一个线程都可以利用线程标识符和一组状态参数进行描述:
    • 寄存器状态:程序计数器PC和堆栈指针中的内容
    • 堆栈:在堆栈中通常保存有局部变量和返回地址
    • 线程运行状态
    • 优先级
    • 线程专有存储器:保存线程自己的局部变量拷贝
    • 信号屏蔽
  • 线程运行状态:
    • 执行状态
    • 就绪状态
    • 阻塞状态

线程的创建和终止

  • 创建:线程的创建使用对应的系统调用即可
  • 终止:
    • 线程完成工作后自动退出
    • 线程出现错误或被其他线程强行终止

需要注意的是: 在大多数的OS中,线程被中止后并不立即释放它所占有的资源,只有当进程中的其他线程执行了分离函数后,被终止的线程才与资源分离, 此时的资源才能被其他线程利用。

这是为了使被终止的线程有机会可以重新运行,为此调用者线程须调用一条被称为“等待线程终止”的连接命令,来与该线程进行连接。

多线程OS中的进程

进程中的多个线程作为运行实体,进程为线程提供资源。此时进程有以下属性:

  • 作为系统资源分配的单位
  • 可包括多个线程
  • 进程不是一个可执行的实体:因为现在线程是一个独立运行的基本单位,所以此时进程已不再是一个可执行的实体。
    • 当用户对一个进程进行直接操作时,也作用于其所有的线程。

线程间的同步和通信

互斥锁(mutex):用户实现对临界资源的互斥访问

条件变量:条件变量用于避免使用互斥锁导致死锁的情况

每一个条件变量通常都与一个互斥锁一起使用,也就是在创建一个互斥锁时便联系着一个条件变量。单纯的互斥锁用于短期锁定, 主要用于保证对临界区的互斥进入。条件变量则用于线程的长期等待,直至所等待的资源成为可用的资源。

条件变量的逻辑就在于:先判断该资源是否可用,如果不可用则释放已经占用的mutex,以避免其他需要使用该mutex的线程阻塞。

信号量:用于线程同步

  • 私用信号量(private semaphore):信号量存在于进程空间中,内核并不知晓。 所以当信号量结束时,如果用户不主动释放其空间,内核将不会自动释放
  • 公用信号量(public semaphore):由内核对其进行管理,当所有占用者释放该信号量时,系统自动回收其空间。

线程的实现方式

内核支持线程KST(Kernel Supported Threads)

无论是系统进程还是用户进程,进程的创建、撤销,以及要求由系统设备完成的I/O操作,都是利用系统调用而进入内核,再由内核中的相应处理程序予以完成的。进程的切换同样是在内核的支持下实现的,因此不论什么进程,都是在操作系统的支持下运行的。

内核空间还为每一个内核支持线程设置了一个线程控制块,内核是根据该控制块而感知某线程的存在并控制。

这种线程实现方式主要有如下4个优点:

  1. 在多处理器系统中,内核能够同时调用同一进程中多个线程并执行
  2. 如果进程中的一个线程被阻塞了,内核可以调度该进程或其他进程中的其他线程占有处理器运行
  3. 内核支持线程具有很小的数据结构和堆栈,线程的切换比较块,切换开销小
  4. 内核本身也可以采用多线程计数,可以提高系统的执行速度和效率

当然也具有以下缺点:

  1. 对于用户的线程切换而言,其模式切换的开销较大。

用户级线程ULT(User Level Threads)

用户级线程仅存在于用户空间中,其控制不需要内核的支持,因而内核完全不知道用户级线程的存在。

但用户级线程的调度单位是进程。

用户级线程的优点:

  1. 线程切换不需要切换到内核空间,节省了切换开销
  2. 调度算法可以是进程专用的:各个进程可以选择不同的调度算法
  3. 用户级线程的实现与操作系统平台无关。

用户级线程的缺点:

  1. 系统调用阻塞问题:由于是以进程为调度单位,当一个线程阻塞时,整个进程都被阻塞。
  2. 多线程应用不能利用多处理器的并行优点。内核每次分配给一个进程仅有一个CPU,因此进程中仅有一个线程能执行,在该线程放弃CPU之前,其他线程只能等待。

组合方式

组合方式结合了二者的优点,并克服了各自的不足。

线程的实现

线程分为内核线程和用户线程。

内核支持线程的实现

系统在创建一个新进程时,便为它分配一个任务数据区PTDA(Per Task Data Area),其中包括若干个线程控制块TCB空间。 每一个TCB就对应用户空间中的TCB。 每当创建一个线程时,便为新线程分配一个TCB(只要不超出其限制的TCB数量)。 当线程被取消时,很多系统并不会释放其TCB空间,这是为了以后创建新线程便可以直接利用该资源或让线程重新再运行。

用户级线程的实现

用户级线程是在用户空间实现的,它们都运行在一个中间系统上面,中间系统分别是运行时系统和内核控制线程。

  • 运行时系统(Runtime System):通过用户空间的库实现了线程的操作集合,并作为用户级线程与内核之间的接口。
    • 通过这种方式实现的线程,在切换的时候不需要内核来实现切换而是直接在用户空间完成,所以其切换速度贼快。
  • 内核控制线程:也叫轻型进程LWP(Light Weight Process),LWP与内核线程连接。
    • 当用户级线程运行时,只要将它连接到一个LWP上,此时它便具有了内核支持线程的所有属性。
    • 用户级线程数量比较多,内核中的LWP与用户级线程是多对多的关系,有可能几个线程多路复用一个LWP
      • 当一个内核线程发生了阻塞,那么通过LWP连接的一个或多个线程都会阻塞。
    • 当用户级线程不需要与内核通信时,并不需要LWP,当要通信时,便需借助于LWP间接操控内核线程。

用户级线程与内核控制线程的连接

在不同的操作系统中,用户线程与内核线程的连接有三种不同的模型:

  • 一对一模型:每个用户线程都有一个对应的内核线程与之连接。
    • 并行能力强,但每创建个用户线程就对应创建一个内核线程,开销较大。
  • 多对一模型:将多个用户线程(通常是同一个进程)映射到一个内核控制线程。
    • 虽然开销小,当一个线程阻塞时,整个进程都会被阻塞。
  • 多对多模型:多个用户线程映射到多个内核线程,内核线程的数目小于或等于用户线程的数目

习题

什么是前趋图?为什么要引入前趋图?

什么是前趋图

前趋图(Precedence Graph)是一个 有向无循环图 ,记为DAG(Directed Acyclic Graph),用于描述进程之间的执行的前后关系,由节点和箭头组成。

  • 每个结点表示一个程序段或进程,乃至一条语句
  • 箭头 -> 表示前趋关系(Precedence Relation)
  • Pi -> Pj ,称Pi是Pj的直接前趋,Pj是Pi的直接后继
    • 没有前趋的结点称为初始结点(Initial Node),没有后继的结点称为终止结点(Final Node)
  • 每个结点还具有一个重量(Weight),用户表示该结点含有的程序里或结点的执行时间

为什么要引入前趋图

通过图形化的方式抽象的展示程序或进程之间的执行关系,比直接看代码要来得简洁明了。

Last Updated 2018-10-14 日 19:32.
Render by hexo-renderer-org with Emacs 26.1 (Org mode 9.1.14)