用信号量实现进程互斥, 同步, 前驱关系

在这里插入图片描述
回顾:

信号量
对应一种资源
信号量的value:
资源的剩余数量
如果小于0表示有进程在等待该资源
P操作:
申请一个资源
如果资源不够就阻塞该进程
V操作
释放一个资源
并检查是否仍有进程等待该资源, 有则唤醒一个进程

实现进程互斥

步骤

  1. 确定临界区
    即确定哪段代码用于访问临界资源

  2. 设置 互斥信号量 mutex, 并初始化

  3. 进入区进行P(mutex)操作以申请资源
    回顾进程互斥的四个逻辑部分
    在这里插入图片描述

  4. 退出区进行V(mutex)操作以释放资源
    在这里插入图片描述

英文翻译:
mutex: 互斥体
semaphore: 信号量

使用semaphore mutex方式定义信号量一般认为是记录型信号量
typedef struct {
	int value;
	struct process *L;
}semaphore;

注意事项

  1. 使用semaphore mutex方式定义信号量一般认为是记录型信号量
  2. 对于不同的临界资源需要设置不同的互斥信号量
  3. PV操作必须成对出现
    缺少P则无法保证临界资源的互斥访问
    缺少V则导致资源无法被释放, 且等待进程无法被唤醒

实现进程同步

回顾

什么是进程同步?
由于进程的并发执行导致的异步的特性, 我们无法确定不同进程中指令的执行顺序
为什么需要进程同步?
比如进程1的指令1必须要在进程2的指令3后面执行, 这时候就需要我们提供进程同步机制来实现

如何利用PV操作来实现进程同步?

考虑P操作中资源数为0时的情况
在这里插入图片描述
先对value–, 然后发现value<0, 该进程阻塞

所以我们可以利用如上特性, 阻止代码的执行

实现进程同步的步骤

  1. 确定需要进行进程同步的地方,
    即哪部分要在前面执行,
    哪部分要在后面执行

  2. 设置同步信号量S, S.value初始化为0

  3. 添加PV操作
    先执行的代码的末尾添加V(S)操作
    后执行的代码的开头添加P(S)操作

semaphore S = 0;

P1 ( ) {
	代码1;
	代码2;
	V(S);
	代码3;
}

P2 ( ) {
	P(S);
	代码4;
	代码5;
	代码6;
}

如上代码中, 代码1,2必然在代码4,5前执行

在没有执行V(S)之前, S=0, 直接执行P(S)
会阻塞该进程

除非执行了V(S)使得S.value++后才能顺利执行P(S)以后的内容

实现进程的前驱关系

利用进程同步中得到的总结:
先执行的代码的末尾添加V(S)操作
后执行的代码的开头添加P(S)操作
在这里插入图片描述

图中:

  • Sn为Pn进程中的某个指令
  • x—>y表示x在y前执行
  • abcdefg分别为自己创建的信号量且他们的value初始都为0
  • V(a)—>P(a)表示在S1执行末尾添加V(a)操作, 在S2开始前添加P(a)操作, 其他同理

总结

在这里插入图片描述
使用信号量实现进程同步与进程的前驱关系时, 特别要注意总结出来的结论:

  1. 先执行的代码的末尾添加V(S)操作
  2. 后执行的代码的开头添加P(S)操作
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BetterChinglish

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值