信号量同步互斥问题

一、信号量

信号量是一种抽象数据类型

  1. 由一个整型(sem)变量和两个原子操作组成
  2. P():sem减1,如果sem<0进入等待状态,否则继续
  3. V():sem加1,如果sem<=0则唤醒一个等待的线程
    这里写图片描述

二、管程

管程是一种用于多线程互斥访问共享资源的程序结构

  1. 局部数据变量只能被管程的过程访问,任何外部过程都不能访问
  2. 一个进程通过调用管程的一个过程进入管程
  3. 在任何时候,只能有一个进程在管程中执行,调用管程的任何其他进程都被阻塞,以等待管程可用

管程的使用

  1. 管理共享数据
  2. 定义访问共享数据的方法

这里写图片描述
条件变量

  1. 条件变量是管程内的等待机制
    1.1. 进入管程的线程因资源被占用而进入等待状态
    1.2. 每个条件变量表示一种等待原因,对应一个等待队列
  2. Wait()操作
    2.1. 将自己阻塞在等待队列中
    2.2. 放弃对管程的互斥访问权限(同一时刻管程只能有一个进程访问)
  3. Signal()操作
    3.1. 将等待队列中的一个线程唤醒(信号量机制中的Signal是释放一个信号量,如果信号量≤0则唤醒一个线程)

三、生产者消费者问题

这里写图片描述
①生产者在生成数据后放在一个缓冲区里
②消费者从缓冲区中读取数据
③任何时刻只能有一个生产者或消费者可以访问缓冲区

问题分析:
①任何时刻只能有一个线程操作缓冲区
②缓冲区满时,生产者要等待消费者
③缓冲区空时,消费者要等待生产者

利用信号量解决
这里写图片描述

利用管程解决
这里写图片描述

四、哲学家就餐问题

问题描述
这里写图片描述

解决方案
这里写图片描述
这里写图片描述
这里写图片描述

五、读者-写者问题

这里写图片描述

管程的状态变量
这里写图片描述

  • AR:正在读的读者数量
  • AW:正在写的写者数量
  • WR:等待读的读者数量
  • WW:等待写的写者数量
  • okToRead:读者的等待队列
  • okToWrite:写者的等待队列

读者模块(写者优先)
这里写图片描述
startRead():如果有写者正在写或等待写,则进入等待队列
DoneRead():如果没有读者在读且有写者等待写,则唤醒写者

写者模块(写者优先)
这里写图片描述
StartWrite():如果有读者在读或有写者在写,则进入等待队列
DoneWrite():如果有写者等待写,则优先唤醒写者,或者唤醒等待的读者

猜你喜欢

转载自blog.csdn.net/qq_31759205/article/details/80700025