并发性:互斥和同步

操作系统设计中的核心问题是进程和线程的管理:

  • 多道程序设计技术:管理单处理器系统中的多个进程
  • 多处理器技术:管理多处理器系统中的多个进程
  • 分布式处理器技术:管理多台分布式计算机系统中多个进程的执行。

并发是所有问题的系统,也是操作系统设计的基础。并发会在一下三种不同的上下文中出现:

  • 多应用程序:多道程序设计技术允许在多个活动的应用程序间动态共享处理器时间。
  • 结构化应用程序:作为模块化设计和结构化程序设计的扩展,一些应用程序可以被有效的设计成一组并发进程
  • 操作系统结构:同样的结构坏程序设计优点可用于系统程序员,操作系统自身常常作为一组进程或县城实现。

这里写图片描述

并发的原理

单处理器的情况下,问题源于多道程序设计系统的一个基本特性:进程的相对执行速度不可预测,它取决于其他进程的活动、操作系统处理中断的方式及操作系统的调度策略。这就带来了下列困难:

  • 全局资源的共享充满了危险。例如,如果两个进程都使用同一个全局变量,并且都对该变量执行读写操作,那么不同的读写执行顺序是非常关键的。
  • 操作系统很难对资源进行最优化分配:例如,进程A可能请求使用一个特定的I/O通道,并获得控制权,但它在使用这个通道前被阻塞了,操作系统仍然锁定这个通道,以防止其他进程使用,这种情况有可能导致死锁。
  • 定位程序设计错误是非常困难的。

控制对共享资源的访问

竞争条件

竞争条件发生在多个进程或者线程读写数据时,其最终的结果依赖于多个进程的指令执行顺序。

假设两个进程P1和P2共享全局变量a。在某一执行时刻,P1更新a为1,在执行的某一时刻,P2更新a为2。因此,两个进程竞争更新变量a。竞争的“失败者”(即最后更新全局变量a的进程)决定了变量a的最终值。

操作系统关注的问题

操作系统必须为每个活跃进程分配和释放各种资源。这些资源包括:

  • 处理器时间
  • 存储器
  • 文件
  • I/O设备

进程的交互

我们可以根据进程相互之间知道对方是否存在的程度,对进程间的交互方式进行分类:

  • 进程之间相互不知道对方的存在
  • 进程间接知道对方的存在
  • 进程直接知道对方的存在:这些进程可以通过进程ID互相通信,用于合作完成某些活动

进程间的资源共享:当并发进程竞争使用同一资源时,它们之间会发生冲突。

竞争进程间没有任何信息交换,但是一个进程的执行可能会影响到竞争进程的行为。特别是当两个进程都期望访问同一个资源的时候,如果操作系统把这个资源分配给一个进程,那么另一个就必须等待。被拒绝访问的进程执行速度就会变慢,甚至被阻塞的进程永远不能访问这个资源,因此该进程永远不能成功结束运行。

竞争进程面临三个控制问题。首先是互斥的要求。假设两个或更多的进程需要访问一个不可共享的资源。这类资源称为临界资源,使用临界资源的那一部分程序称为程序的临界区。一次只允许有一个程序在临界区

实施互斥产生了两个额外的控制问题。一个是死锁。例如,考虑两个进程P1和P2,以及两个资源R1和R2,假设每个进程执行部分功能都需要访问这两个资源,那么就有可能出现下列情况:操作系统把R1分配给P2,把R2分配给P1,每个进程都在等待另一个资源,且在获得其他资源并完成功能前,谁都不会释放自己已经拥有的资源,这两个进程就会发生死锁。

另一个控制问题是饥饿。这里写图片描述

假设有n个进程并发执行,每个进程包括了在某资源Ra操作的临界区,以及不涉及资源Ra的其他代码。因为所有的进程都需要访问同一资源Ra,因此在同一时刻只有一个进程在临界区是很重要的。为实施互斥,需要两个函数:entercritical和exitcritical。每个函数的参数都是竞争使用的资源名。如果另外一个进程在它的临界区中,那么任何试图进入临界区的进程都必须等待。

进程间通过共享的合作:通过共享进行合作的情况,包括进程间在互相并不确切知道对方的情况下进行交互。多个进程可能访问一个共享变量、共享文件或数据库,进程可能使用并修改共享变量而并不涉及其他进程,但却知道其他进程也可能访问同一个数据。因此,这些进程必须合作,以确保它们共享的数据得到正确管理。控制机制必须确保共享数据的完整性。

可以以两种不同的模式(读和写)访问数据项,并且只有写操作必须保证互斥。

数据的一致性:假设两个数据项a和b保持着相等关系a=b,为保持这个关系,任何一个程序如果修改了其中一个变量,也就必须修改另一个。这里写图片描述

如果最初状态是一致的,则单独执行每个进程会使共享数据仍然保持一致状态。这里写图片描述

如果执行这个顺序,结果不再保持a=b。例如,开始时由a=b=1,在这个执行序列结束时有a=4和b=3。为了避免这个问题,可以把每个进程中的整个序列声明成一个临界区。

进程间通过通信的合作:当进程通过通信进行合作时,各个进程都与其他进程进行连接,通信提供了同步和协调各种活动的方法。

在典型情况下,通信可由各种类型的消息组成,发送消息和接收消息的原语由程序设计语言提供。

由于传递消息的过程中,进程间未共享任何对象,因而这类合作不需要互斥,但是仍然存在死锁和饥饿的问题。

互斥的要求

为了提供对互斥的支持,必须满足一下要求:

  • 必须强制实施互斥:在与相同资源或共享对象的临界区有关的所有进程中,一次只允许一个进程进入临界区
  • 一个在非临界区停止的进程不能干涉其他进程
  • 决不允许出现需要访问临界区的进程被无限延迟的情况,即不会死锁或饥饿
  • 当没有进程在临界区时,任何需要进入临界区的进程必须能够立即进入
  • 一个进程驻留在临界区的时间必须是有限的

信号量

操作系统和用于提供并发性的程序设计语言机制。
这里写图片描述

基本原理:两个或多个进程可以通过简单的信号进行合作,一个进程可以被迫在某一位置停止,直到它接收到一个特定信号。为了发信号,需要使用一个称为信号量的特殊变量。为通过信号量s传送信号,进程可执行原语semSignal(s);为通过信号量s接收信号,进程可执行原语semWait(s);如果相应的信号仍然没有发送,则进程被阻塞,直到发送完为止。

可以把信号量视为一个具有整数值的变量,在它之上定义三个操作:

  • 一个信号量可以初始化成非负数
  • semWait操作使信号量减1。若值为负数,则执行semWait的进程被阻塞。否则进程继续执行。
  • semSignal操作使信号量加1,若值小于或等于零,则被semWait操作阻塞的进程被接触阻塞。
    这里写图片描述

二元信号量:二元信号量的值只能是0或1,可以使用下面三种操作:

  • 一个二元信号量可以初始化成0或 1
  • semWaitB操作检查信号的值,如果值为0,那么进程执行semWaitB就会受阻。如果值为1,那么将值改变为0,并且继续执行该进程。
  • semWaitB操作检查是否有任何进程在该信号上受阻,如果有,那么通过semWaitB操作,受阻的进程就会被唤醒,如果没有进程受阻,那么值被设置为1。

这里写图片描述

与二元信号量相关的一个概念是互斥量。两者的关键区别在于为互斥量加锁的进程和为互斥量解锁的进程必须是同一个进程。相比之下,可能由某个进程对二元信号量进行加锁操作,而由另一个进程为其解锁。

不论是计数信号量还是二元信号量,都需要使用队列来保存在信号量上等待的进程。

  • 强信号量(FIFO)
  • 弱信号量

互斥

下图给出了一个使用信号量s解决互斥问题的方法。
这里写图片描述

设有n个进程,用数组P(i)表示,所有的进程都需要访问共享资源。每个进程中进入临界区前执行semWait(s),如果s的值为负,则进程被阻塞;如果值为1,则s减为0,进程立即进入临界区;由于s不再为正,因而其他任何进程都不能进入临界区。(信号量保护共享资源)

生产者与消费者问题

这里写图片描述

消息传递

进程交互时,必须满足两个基本要求:同步和通信。为实施互斥,进程间需要同步;为了合作,进程间需要交互信息,—-消息传递。

消息传递的实际功能以一对原语的形式提供:

send(destination, message)
receive(source, message) 

一个进程以消息的形式给另一个执行的目标进程发送信息;进程通过执行receive原语接收信息,receive原语中指明发送消息的源进程和消息。

同步

两个进程间的消息通信隐含着某种同步的信息:只有当一个进程发送消息之后,接收者才能接收消息。

发送者和接收者都可以阻塞或不阻塞。

  • 阻塞send,阻塞receive:发送者和接收者都被阻塞,直到完成信息的投递
  • 无阻塞send,阻塞receive:尽管发送者可以继续,但接收者被阻塞直到请求的消息到达
  • 无阻塞send,无阻塞receive

寻址

在send原语中确定哪个进程接收消息是很有必要的。大多数实现允许接收进程指明消息的来源。

在send和receive原语中确定目标和源进程的方案可分为两类:直接寻址和间接寻址。对于直接寻址,send原语包含目标进程的标识号,而receive原语有两种处理方式。一种是要求进程显式的指定源进程,因此,该进程必须事先知道希望得到来自哪个进程的消息,这种方式对于处理并发进程间的合作是非常有效的。另一种情况是不可能指定所期望的源进程,例如,打印机服务进程将接受来自各个进程的打印请求,对这类应用使用隐式寻址更有效。

间接寻址:消息不是直接从发送者发送到接收者,而是发送到一个共享数据结构,该结构由临时保存消息的队列组成,这些队列通常称为信箱。对于两个通信进程,一个进程给合适的信箱发送消息,另一个进程从信箱中获得这些消息。

消息格式

这里写图片描述

排队原则

最简单的排队原则是先进先出原则。一个可选的原则是允许指定消息的优先级。另一种允许接收者检查消息队列并选择下一次接收哪个消息。

互斥

下图是可用于实施互斥的消息传递方式。
这里写图片描述

假设使用阻塞receive原语和无阻塞send原语,一组并发进程共享一个信箱box,它可供所有进程在发送和接收消息时使用,该信箱被初始化成一个无内容的消息。希望进入临界区的进程首先试图接收一条消息,如果信箱为空,则该进程被阻塞;一旦进程获得消息,它执行它的临界区,然后把消息放回信箱。

小结

互斥指的是,对一组并发进程,一次只有一个进程能够访问给定的资源或执行给定的功能。互斥技术用于解决诸如资源争用之类的冲突,还可以用于进程间的同步,使得它们可以合作。

支持互斥的另一种方法是在操作系统中提供相应的功能,其中最常见的两种技术是信号量和消息机制。信号量用于在进程间发信号,并可以很容易实施一个互斥协议。消息对实施互斥是很有用的,还为进程间的通信提供了一种有效的方法。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值