计算机操作系统 第二章:进程的描述与控制(下)(知识梳理+脑图)

计算机操作系统

由于本学期学习了计算机操作系统,所以打算边学习边整理,一方面帮助自己梳理知识结构,另一方面可以帮助大家理解。

注意:该总结用的是汤小丹第四版!

关于知识脑图,我是边学边做的,推荐大家也自己做脑图,而不是直接拿走照搬,因为只有自己梳理的东西才是自己的

做知识脑图的好处是可以对知识整体结构有好的把握,不会让自己迷失于细节;还可以复习时快速找到知识点等。

废话不多说,赶紧开始吧。
知识脑图

第二章 进程的描述与控制(下)

五、经典进程的同步问题

1、生产者—消费者问题

前面我们已经对生产者—消费者问题(The proceducerconsumer problem)做了一些描述,但未考虑进程的互斥与同步问题,因而造成了数据counter的不定性。由于生产者—消费者问题是相互合作的进程关系的一种抽象,例如, 在输入时,输入进程是生产者,计算进程是消费者;而在输出时,则计算进程是生产者,而打印进程是消费者, 因此,该问题有很大的代表性及实用价值。

  1. 利用记录型信号量解决生产者—消费者问题
    假定在生产者和消费者之间的公用缓冲池中,具有n个缓冲区, 这时可利用互斥信号量mutex实现诸进程对缓冲池的互斥使用; 利用信号量empty和full分别表示缓冲池中空缓冲区和满缓冲区 的数量。只要缓冲池未满,生产者便可将消息送入缓冲池;只要缓冲池未空,消费者便可从缓冲池中取走一个消息。 对生产者—消费者问题可描述如下:
    生产者与消费者问题图示

    在生产者—消费者问题中应注意:首先,在每个程序中用于实现互斥的wait(mutex)和signal(mutex)必须成对地出现; 其次,对资源信号量empty和full的wait和signal操作,同样需要成对地出现,但它们分别处于不同的程序中。例如,wait(empty)在计算进程中,而signal(empty) 则在打印进程中,计算进程若因执行wait(empty)而阻塞,则以后将由打印进程将它唤醒;

    最后,在每个程序中的多个wait操作顺序不能颠倒。应先执行对资源信号量的wait操作,然后再执行对互斥信号量的wait操作,否则可能引起进程死锁。

  2. 利用AND信号量解决生产者—消费者问题

  3. 利用管程解决生产者-消费者问题
    在利用管程方法来解决生产者-消费者问题时, 首先便是为它们建立一个管程,并命名为Proclucer-Consumer, 或简称为PC。其中包括两个过程:
    (1) put(item)过程。生产者利用该过程将自己生产的产品投放到缓冲池中,并用整型变量count来表示在缓冲池中已有的产品数目,当count≥n时,表示缓冲池已满,生产者须 等待。
    (2) get(item)过程。消费者利用该过程从缓冲池中取出一个产品,当count≤0时,表示缓冲池中已无可取用的 产品, 消费者应等待。

    在利用管程解决生产者-消费者问题时, 其中的生产者和消费者可描述为:

2、哲学家进餐问题
  1. 利用记录型信号量解决哲学家进餐问题
    经分析可知,放在桌子上 的筷子是临界资源,在一段时间内只允许一位哲学家使用。为了实现对筷子的互斥使用,可以用一个信号量表示一只筷子,由 这五个信号量构成信号量数组。其描述如下:
    在这里插入图片描述
    存在哲学家同时拿起左边筷子的可能,存在死锁可能。

    可采取以下几种解决方法:
    (1) 至多只允许有四位哲学家同时去拿左边的筷子, 最终能保证至少有一位哲学家能够进餐,并在用毕时能释放出他用过的两只筷子,从而使更多的哲学家能够进餐。
    (2) 仅当哲学家的左、右两只筷子均可用时,才允许他拿起筷子进餐。
    (3) 规定奇数号哲学家先拿他左边的筷子,然后再去拿右边的筷子;而偶数号哲学家则相反。按此规定,将是 1、2号哲学家竞争1号筷子;3、4号哲学家竞争3号筷子。 即五位哲学家都先竞争奇数号筷子,获得后,再去竞争偶数号筷子。

  2. 利用AND信号量机制解决哲学家进餐问题在哲学家进餐问题中,要求每个哲学家先获得两个临界资源(筷子)后方能进餐,这在本质上就是前面所介绍的AND同步问题,故用AND信号量机制可获得最简洁的解法。

3、读者-写者问题
  1. 利用记录型信号量解决读者-写者问题读者与写者问题
    (1)读者可以同时读;
    (2)读者与写者不能同时;
    (3)写者之间也不能同时。

    为实现Reader与Writer进程间在读或写时的互斥而设置了一个互斥信号量Wmutex。另外,再设置一个整型变量Readcount表示正在读的进程数目。 仅当Readcount=0, Reader 进 程 才 需 要 执 行 Wait(Wmutex) 操作。 若 wait(Wmutex)操作成功,Reader进程便可去读,相应地,做Readcount+1 操作。同理,仅当Reader进程在执行了Readcount减1操作后其值为0时, 才须执行signal(Wmutex)操作,以便让Writer进程写。又因为Readcount 是一个可被多个Reader进程访问的临界资源,因此,应该为它设置一个互斥信号量rmutex。

  2. 利用信号量集机制解决读者-写者问题

六、进程通信

信号量通信不够理想:效率低;通信不够透明。 进程间传送大量数据,就要用到高级通信工具,其特点:
(1)使用方便;
(2)高效地传送大量数据。

1、进程通信的类型
  1. 共享存储器系统(Shared-Memory System)
    (1)基于共享数据结构的通信方式。
    传递少量数据,效率低
    (2)基于共享存储区的通信方式。

  2. 管道(Pipe)通信系统
    所谓“管道”,是指用于连接一个读进程和一个写进程以实现他们之间通信的一个共享文件(内存页), 又名pipe文件。向管道(共享文件)提供输入的发送进程 (即写进程), 以字符流形式将大量的数据送入管道;而接受管道输出的接收进程(即读进程),则从管道中接收(读)数据。由于发送进程和接收进程是利用管道进行通信的,故又称为管道通信

    这种方式首创于UNIX系统,由于它能有效地传送大量数据,因而又被引入到许多其它操作系统中。

    为了协调双方的通信,管道机制必须提供以下三方面的协调能力:
    互斥,即当一个进程正在对pipe执行读/写操作时,其它(另一)进程必须等待。
    同步,指当写(输入)进程把一定数量(如4 KB)的数据写 入pipe,便去睡眠等待, 直到读(输出)进程取走数据后,再把他唤醒。当读进程读一空pipe时,也应睡眠等待,直至写进程将数据写入管道后,才将之唤醒。
    确定对方是否存在,只有确定了对方已存在时,才能进行通信。

  3. 消息传递系统(Message passing system)
    在消息传递系统中,进程间的数据交换,是以格式化的消息 (message)为单位的;在计算机网络中,又把message称为报文

    程序员直接利用系统提供的一组通信命令(原语)进行通信。操作系统隐藏了通信的实现细节,大大减化了通信程序编制的复杂性,而获得广泛的应用。

    因其实现方式的不同而进一步分成直接通信方式间接通信方式两种。
    直接通信方式:发送进程利用OS所提供的发送原语,直接把消息发送给目标进程。
    间接通信方式:发送和接收进程,都通过共享中间实体的方式完成进程间的通信。

  4. 客户机-服务器系统(Client-server system)
    客户机-服务器系统的通信机制,已成为网络环境下各种应用的主流,其主要实现方式分为三类:套接字、远程过程调用和远程方法调用

    (1)套接字
    套接字就是一个通信标识类型的数据结构,包含了通信目的的地址、通信使用的端口号、通信网络的传输协议、进程所在的网络地址,以及针对客户或服务器程序提供的不同系统调用(或API函数等),是进程通信和网络通信的基本构件。

    套接字是为客户/服务器模型而设计的,通常套接字包括两类:
     基于文件型:本地通信,类似于管道;
     基于网络型:通信双方被分配一对套接字,通信结束时,系统通过关闭接收进程(或服务器端)的套接字撤销连接。

    套接字的优势: 本地及网络均可; 套接字号具有唯一性,易于区分; 隐藏了通信设施及实现细节。

    (2)远程过程调用和远程方法调用

    远程过程(函数)调用RPC,是一个通信协议,用于通过网络连接的系统。
    负责处理远程过程调用的进程有两个:本地客户进程以及远程服务器进程。也被称为网络守护进程,通常二者处于阻塞状态、等待消息。
    RPC通过引入存根而实现透明性,即在本地客户端每个能够独立运行的远程过程都拥有一个客户存根,本地进程调用远程过程实际是调用该过程关联的存根;同样,即在服务器端每个能够独立运行的远程过程都拥有一个服务器存根,远程过程主要 步骤参见P76。

2、消息传递通信的实现方式
  1. 直接消息传递系统
    (1) 直接通信原语

    ①对称寻址方式 —— 一对一
    要求发送进程和接收进程都以显示方式提供对方的标识符, 系统提供下述两条通信命令(原语) :
    send(receiver, message) 发送一个消息给接收进程;
    receive(sender, message); 接收Sender发来的消息;
    例如,原语Send(P2, m1)表示将消息m1发送给接收进程P2; 而原语Receive(P1,m1)则表示接收由P1发来的消息m1。

    该方法的不足:一旦进程更名,通信调用都要更改。

    ②非对称寻址方式 ——多对一
    接收进程可能需要与多个发送进程通信,不需要命名发送进程;
    例如,用于提供打印服务的进程,它可以接收来自任何一个进程的“打印请求”消息。
    发送原语:send(P, message); //发送需要命名接收进程P
    接收原语:receive (id, message); //可以接收来自任何进程的消息,id变量为发送方进程的 id 或名字。

    (2) 消息的格式
    定长消息格式,可以减少对消息的处理和存储开销。这种方式可用于办公自动化系统中,为用户提供快速的便笺式通信;

    变长的消息格式,系统在处理和存储时,须付出更多的开销,但方便了用户

    这两种消息格式各有其优缺点,故在很多系统(包括计算机 网络)中,是同时都用的。

    (3) 进程的同步方式
    进程之间通信,同样需要有进程同步机制,有3种方式:
    阻塞发送、阻塞接收。用于进程间双向通信,发送进程和接收进程之间无缓冲。即通信双方联系非常紧密,得到对方的应答才能推进。
    不阻塞发送、阻塞接收。普遍,适合于那些不等待消息的到来就无法继续工作的进程。如服务器上的服务进程,平时总是处于阻塞状态,只有在请求服务的消息到达时,它们才会被唤醒以便提供服务。
    既不阻塞发送也不阻塞接收。常用于分布式系统中,因为采用阻塞方式进行通信时,一旦传递的数据丢失,将会使阻塞进程无限期地等待下去。而采用非阻塞、接收的方式就可以避免这种情况。接收进程有消息时就处理消息,无消息时继续执行。

    (4) 通信链路
    为使在发送进程和接收进程之间能进行通信,必须在两者之间建立一条通信链路。 有两种方式建立通信链路:

    第一种方式是:由发送进程在通信之前,用显式的“建立连接”命令(原语)请求系统为之建立一条通信链路;在链路使用完后,也用显式方式拆除链路。这种方式主要用于计算机网络中。

    第二种方式是:发送进程无须明确提出建立链路的请求,只须利用系统提供的发送命令(原语),系统会自动地为之建立一条链路。这种方式主要用于单机系统中。

    根据通信链路的连接方法,又可把通信链路分为两类:
    ① 点—点连接通信链路,这时的一条链路只连接两个结点(进程);
    ② 多点连接链路,指用一条链路连接多个( n >2)结点(进程)。

    而根据通信方式的不同,则又可把链路分成两种:
    ① 单向通信链路,只允许发送进程向接收进程发送消息;
    ② 双向链路,既允许由进程A向进程B发送消息,也允许进程B同时向进程A发送消息。

  2. 信箱通信----间接通信方式
    (1) 信箱的结构信箱定义为一种数据结构,在逻辑上,可将其分为2个部分:
    ①信箱头:信箱的描述信息;
    ②信箱体:由存放消息的消息格组成。
    双向信箱示意图
    (2) 信箱通信原语
    系统为信箱通信提供了若干条原语, 有:

    信箱的创建和撤消。进程可利用信箱创建原语来建立一个新信箱。创建者进程应给出信箱名字、信箱属性(公用、私用或共享);对于共享信箱, 还应给出共享者的名字。当进程不再需要该信箱时,可用信箱撤消原语将之撤消。
    消息的发送和接收。当进程之间要利用信箱进行通信时,必须使用共享信箱,并利用系统提供的下述通信原语进行通信。
    Send(mailbox, message); 将一个消息发送到指定信箱;
    Receive(mailbox, message); 从指定信箱中接收一个消息;

    (3) 信箱的类型
    信箱可由操作系统创建,也可由用户进程创建,创建者是信箱的拥有者。 据此,可把信箱分为以下三类:

    ① 私用信箱
    用户进程可为自己建立一个新信箱,并作为该进程的一部分。信箱的拥有者有权从信箱中读取消息,其他用户则只能将自己构成的消息发送到该信箱中。这种私用信箱可采用单向通信链路的信箱来实现。 当拥有该信箱的进程结束时,信箱也随之消失。

    ②公用信箱
    它由操作系统创建,并提供给系统中的所有核准进程使用。核准进程既可把消息发送到该信箱中,也可从信箱中读取发送给自己的消息
    显然,公用信箱应采用双向通信链路的信箱来实现。通常,公用信箱在系统运行期间始终存在。

    ③共享信箱
    它由某进程创建,在创建时或创建后,指明它是可共享的,同时须指出共享进程(用户)的名字。信箱的拥有者和共享者,都有权从信箱中取走发送给自己的消息

    在利用信箱通信时,在发送进程和接收进程之间,存在以下四种关系:
    ①一对一关系。这时可为发送进程和接收进程建立一条两者专用的通信链路, 使两者之间的交互不受其他进程的干扰。
    ②多对一关系。允许提供服务的进程与多个用户进程之间进行交互,也称为客 户/服务器交互。
    ③一对多关系。允许一个发送进程与多个接收进程进行交互, 使发送进程可用广播方式,向接收者(多个)发送消息。
    ④多对多关系。允许建立一个公用信箱,让多个进程都能向信箱中投递消息;也可从信箱中取走属于自己的消息。

3、直接消息传递系统实例
  1. 消息缓冲队列通信机制中的数据结构
    (1) 消息缓冲区
    在消息缓冲队列通信方式中,主要利用的数据结构是消息缓冲区。它可描述如下:

(2) PCB中有关通信的数据项
在利用消息缓冲队列通信机制时,还应增加用于对消息队列进行操作和实现同步的信号量,并将它们置入进程的PCB中。 在PCB中应增加的数据项可描述如下:

2. 发送原语


七、线程(Threads)的基本概念

1、线程的引入
  1. 进程的2个基本属性
     拥有资源的独立单位
     独立调度和分派的基本单位

  2. 程序并发执行所需付出的时空开销
    1)创建进程
    2)撤消进程
    3)进程切换

    传统的进程“太重”,在多处理机环境(如对称多处理机SMP)下进程调度、分派和切换时都需花费较大的时间和空间开销。

  3. 线程作为调度和分派的基本单位
    • 线程设计的指导思想:
    若进程的两个属性分开,即对于作为调度和分派的基本单位,不同时作为拥有资源的单位,以做到“轻装上阵”;而对于拥有资源的基本单位,又不对之进行频繁的切换
    (1)轻型实体。
    (2)可并发执行。
    (3)共享进程资源。
    适宜多处理机系统

2、线程与进程的比较

3、线程的状态和线程控制块
  1. 线程运行的三个状态
    如同传统的进程一样,在各线程之间也存在着共享资源和相互合作的制约关系,致使线程在运行时也具有间断性。 相应地,线程在运行时,也具有下述三种基本状态:

    执行状态,表示线程正获得处理机而运行;
    就绪状态, 指线程已具备了各种执行条件,一旦获得CPU便可执行的状态;
    阻塞状态,指线程在执行中因某事件而受阻,处于暂停执行时的状态。

  2. 线程控制块TCB
    在OS中的每一个线程都可以利用线程标识符和一组状态参数进行描述,即线程控制块。通常有这样几项:
     线程标识符
     寄存器状态, 它包括程序计数器PC和堆栈指针中的内容;
     堆栈, 在堆栈中通常保存有局部变量和返回地址;
     线程运行状态, 用于描述线程正处于何种运行状态;
     优先级, 描述线程执行的优先程度;
     线程专有存储器, 用于保存线程自己的局部变量拷贝;
     信号屏蔽, 即对某些信号加以屏蔽。

  3. 多线程OS中的进程属性
    在多线程OS中,进程是作为拥有系统资源的基本单位,通常的进程都包含多个线程并为它们提供资源,但此时的进程就不再作为一个执行的实体。 多线程OS中的进程有以下属性:
    (1) 作为系统资源分配的单位。
    (2) 可包括多个线程。
    (3) 进程已不是一个可执行的实体。
    多线程进程模块

八、线程的实现

1、线程的实现方式
  1. 内核支持线程
    这里所谓的内核支持线程,即无论是用户进程中的线程,还是系统进程中的线程,他们的创建、撤消和切换等,也是依靠内核实现的。此外,在内核空间还为每一个内核支持线程设置了一个线程控制块,内核是根据该控制块而感知某线程的存在的,并对其加以控制。

    内核支持线程的优缺点
    • 优点
    (1)多处理器系统中,同一进程中的线程可以并行;
    (2)内核知道进程中的线程运行情况;
    (3)线程切换开销小;
    (4)内核本身也可以采用多线程技术,以提高系统的执行速度和效率。
    • 缺点
    同一进程下的线程切换开销比较大。

  2. 用户级线程
    用户级线程是与内核无关。用户级线程仅存在于用户空间中。对于这种线程的创建、撤消、线程之间的同步与通信等功能,都无须利用系统调用来实现。对于用户级线程的切换, 通常是发生在一个应用进程的诸多线程之间,无须内核的支持。 由于切换的规则远比进程调度和切换的规则简单,因而使线程的切换速度特别快

    系统仍然是以进程为单位进行调度的容易发生线程当前状态与实际 状态不相吻合的情况。如某线程运行过程中请求I/O,于是系统将该线程 所在的进程置入阻塞状态。同一进程下的线程即使具备运行条件,也不会被调度;而当前线程理应是阻塞状态,但实际上仍是运行状态,因为系统不对线程进行操作。再比如系统采用时间片轮转法,A、B两个进程轮流执行,但是A进程只有两个线程,而B进程则有20个线程,显然这种调度对B进程而言就是不公平的。若想以线程为单位进行调度,系统就应该识别线程,这就得采用内核支持级线程。

    用户级线程的优缺点
    • 优点
    (1)同一进程下的线程切换开销小,不用内核状态;
    (2)调度算法可以是进程专用的;
    (3)用户级线程的实现与OS平台无关;
    • 缺点
    (1)系统调用导致同一进程下的所有线程阻塞;
    (2)不能利用多处理机进行多重处理,进程中仅有一个线程能执行,其他线程只能等待。

  3. 组合方式
    将用户级线程和内核支持级线程进行组合。 组合方式中,内核支持内核支持级线程的建立、调度和管理, 同时也允许用户应用程序建立、调度和管理用户级线程

    用户级线程与内核控制线程的连接(3种连接模型)
    1)一对一模型 为每一个用户线程都设置一个内核控制线程与之连接。
    优势:开销小,效率高
    劣势:一个线程阻塞,整个进程阻塞;映射到一个内核的多线程不能使用多处理机
    2)多对一模型 将多个用户线程映射到一个内核控制线程。
    优势:更好的并发性,一个线程阻塞,允许调度另一个线程执行;
    劣势:开销大;整个系统线程数有限;
    3)多对多模型 将多个用户线程映射到多个内核控制线程。
    结合上述两种方式的优势
    多线程模型

2、线程的实现
  1. 内核支持线程的实现
    系统在创建一个新进程时,便为它分配一个任务数据区PTDA(Per Task Data Area),其中包括若干个线程控制块TCB空间。

    内核支持线程的创建、撤销、调度与切换,与进程管理相类似。
    任务数据区空间

  2. 用户级线程的实现 (两种方式实现)
    1)运行时系统(Runtime System)
    所谓“运行时系统”,实质上是用于管理和控制线程的函数(过程)的集合, 其中包括用于创建和撤消线程的函数、 线程同步和通信的函数以及实现线程调 度的函数等。正因为有这些函数,才能使用户级线程与内核无关。运行时系统中的所有函数都驻留在用户空间,并作为用户级线程与内核之间的接口。

    线程是通过运行时系统来请求系统的资源的。

    2)内核控制线程
    这种线程又称为轻型进程LWP(Light Weight Process)。 每一个进程都可拥有多个LWP,同用户级线程一样,每个LWP都有自己的数据结构(如TCB),其中包括线程标识符、优先级、状态,另外还有栈和局部存储区等。它们也可 以共享进程所拥有的资源。LWP可通过系统调用来获得内核提供的服务,这样,当一个用户级线程运行时,只要 将它连接到一个LWP上,此时它便具有了内核支持线程的所有属性。

    用户级线程共享LWP,把LWP做成线程池
    利用轻型进程作为中间系统

3、线程的创建和终止
  1. 线程的创建
    在多线程OS环境下,应用程序在启动时,通常仅有一个线程在执行,该线程被人们称为“初始化线程”。它可根据 需要再去创建若干个线程。在创建新线程时,需要利用一个线程创建函数(或系统调用),并提供相应的参数,如指向线程主程序的入口指针、堆栈的大小,以及用于调度的优先级等。在线程创建函数执行完后,将返回一个线程标识符供以后使用。
  2. 线程的终止
    终止线程的方式有两种:一种是在线程完成了自己的工作后自愿退出;另一种是线程在运行中出现错误或由于某种原因而被其它线程强行终止。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值