2.15、用信号量机制实现进程互斥、同步、前驱关系

image-20230201234139626

1、信号量机制实现进程互斥

  1. 分析并发进程的关键活动,划定临界区(如:对临界资源打印机的访问就应放在临界区)

  2. 设置 互斥信号量 \color{red}互斥信号量 互斥信号量 mutex 初值为 1 \color{red}初值为 1 初值为1

  3. 在临界区之前执行 P(mutex)

  4. 在临界区之后执行 V(mutex)

image-20230202001741953

要会自己定义记录型信号量,但如果题目中没特别说明,可以把信号量的声明简写成这种形式

  • semaphore mytex = 1

注意:对不同的临界资源需要设置不同的互斥信号量

image-20230202001958999

P、V 操作必须成对出现 \color{red}\texttt{P、V} 操作必须成对出现 PV操作必须成对出现

  • 缺少 P(mutex) 就不能保证临界资源的互斥访问
  • 缺少 V(mutex) 会导致资源用不被释放,等待进程永不被唤醒

2、用信号量机制实现进程同步

image-20230202002411247

比如,P1P2 并发执行,由于存在异步性,因此二者交替推进的次序是不确定的。

P2 的 “代码 4 ” 要基于 P1 的 “代码 1 ” 和 “代码 2 ” 的运行结果才能执行,

  • 那么我们就必须保证 “代码 4 ” 一定是在 “代码 2 ” 之后才会执行。

这就是进程同步问题,让本来异步并发的进程互相配合,有序推进。


用信号量实现进程同步

  1. 分析什么地方需要实现 “同步关系” ,即必须保证 “一前一后” 执行的两个操作(或两句代码)

  2. 设置 同步信号量 \color{red}同步信号量 同步信号量 S, 初始为 0 \color{red}初始为0 初始为0

  3. 在 “前操作 之后 \color{red}之后 之后执行 V(S)

  4. 在 “后操作 之前 \color{red}之前 之前执行 P(S)

image-20230202003110757

若先执行到 V(S) 操作,则 S++S=1

  • 之后当执行到 P(S) 操作时,由于 S=1 ,表示有可用资源,会执行 S--S 的值变回 0P2 进程不会执行 block 原语,而是继续往下执行代码 4 4 4
  • 说明代码 2 2 2 肯定是先于代码 4 4 4 执行的

若先执行到 P(S) 操作,由于 S=0S--S=-1,表示此时没有可用资源,

  • 因此 P 操作中会执行 block 原语,主动请求阻塞。之后当执行完代码 2 2 2,继而执行 V(S) 操作,S++,使 S变回 0 0 0,由于此时有进程在该信号量对应的阻塞队列中,因此会在 V 操作中执行 wakeup 原语,唤醒 P2 进程。这样 P2 就可以继续执行代码 4 4 4

可以理解为 Java 中的 LockSupport.park()LockSupport.unpark(...)

  • LockSupport.park() 对应 P(S)
  • LockSupport.unpark(...) 对应 V(S)

LockSupport与线程中断


3、用信号量机制实现前驱关系!!

image-20230202005301540

4、整体框架

image-20230202005851995

除了互斥、同步问题外,还会考察有多个资源的问题,有多少资源就把信号量初值设为多少。

  • 申请资源时进行 P 操作,释放资源时进行 V 操作即可
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值