目录

进程同步与互斥

操作系统中的并发进程有些是独立的, 有些需要相互协作.进程之间的协作关系包括互斥、同步、通信。

  • 互斥:多个进程不能同时使用同一个资源,当某个进程使用某种资源时,其他要使用该资源的进程必须等待。
  • 同步:多个进程中发生的事情存在着某种时序关系,某些进程的执行必须先于另一些进程。
  • 通信:多个进程之间要传递一定量的信息。

基础概念

  • 临界资源: 在某段时间内只允许一个进程使用的资源。
  • 临界区: 进程中访问临界资源的那段程序。

进程并发执行的条件(Bernstein condition)

假设R(Pi)={a1,a2,…,am}表示程序Pi在执行期间所要参考的所有变量的集合,称为“读集”。W(Pi)={b1,b2,…,bn}表示程序Pi执行期间要改变的所有变量的集合,称为“写集”。两个程序P1和P2并发执行的条件是:

当且仅当R(P1)∩W(P2)∪R(P2)∩W(P1)∪W(P1)∩W(P2)={}。

进程访问临界区的一般结构

  1. 进入区:对临界资源进行检查,看他是否正在被访问。如果未被访问则可进入,并设置它正被访问的标志。如正被访问,则不能进入。
  2. 临界区:访问临界资源。
  3. 退出区:将临界区正被访问的标志恢复为未被访问。
  4. 剩余区:除上述之外的区域。

互斥访问的实现方式

实现互斥有多种方法:

  1. 让希望并发执行的进程自己完成,不需要操作系统提供任何支持;
  2. 使用专门的机器指令来完成,与具体的硬件系统相关,难成为通用方案;
  3. 由操作系统提供支持。

硬件实现

  • 禁止中断

    在临界区内的进程不能被中断,故保证了互斥进入临界区。只适用于单处理机。

  • 专用机器指令(原子指令/原语操作,防止被调度)

    • TS(Test and Set)指令
    • Swap指令

    都是给临界资源设置一个布尔变量lock,表示资源的两种状态,true表示正被占用;false表示空闲。在进入区中检查lock变量,在退出区中检查

软件实现

通过平等协商方式实现进程互斥。基本思路是在进入区检查和设置一些标志,如果有进程在临界区,则在进入区通过循环检查进行等待;在退出区修改标志。

  • 单标志算法
  • 双标志、先检查算法
  • 双标志、先修改后检查算法
  • 先修改、后检查、后修改者等待算法。

上述算法在进程数上有很大局限性,不同的进程数,代码不一样。故很少使用。

信号量和PV操作

信号量:包含一个整型数值s.value和一个s上的等待队列s.queue,信号量只能通过P、V原语来操作。

原语:。。。

信号量的物理意义

s.value表示系统中某种资源的数目(并不是资源本身),因此又称为资源信号量。

p操作意味着进程请求一个资源,如果无法满足,进程将自我阻塞,并将自己投入s.queue.

v操作意味着进程释放一个资源,当有进程在s.queue上等待时,还会从中唤醒一个进程。

s.value<0时,其绝对值表示等待队列中的进程数。

用信号量解决互斥问题

当s.value=1时,表示仅有一个资源,即仅允许一个进程访问临界区,此时的信号量转换为互斥信号量。通常定义为mutex=1.

在进入区使用P操作申请资源,失败则阻塞自己。 在退出区使用V操作释放资源,从等待队列中唤醒一个阻塞进程。

用信号量解决同步问题

如果进程P2必须在进程P1执行完成之后才执行,则可以设置一个信号量s.value=0. 在P1的尾部V(s), 给信号量+1,在P2头部使用P(s),即可控制先后顺序。

这类思想,可以推广到多各进程当中,但麻烦之处是,n个先后关系需要n个信号量。