17.进程同步与死锁——信号量临界区保护

1.温故知新

通过对信号量的访问和修改,让进程有序推进
问题: empty值必须是正确的,如果empty错了,就不能有序推进了

2.共同修改信号量引出的问题

//生产者
Producer(item)
{
    P(empty);//生产者先判断 缓存区个数 empty是否满了,empty == 0,阻塞
    ...
}

//生产者P1
register = empty;
register = register - 1;
empty = register;

//生产者P2
register = empty;
register = register - 1;
empty = register;

//初始情况
empty = -1; //空闲缓冲区的个数,-1表示有一个进程在睡眠

//一个可能的执行(调度)
P1.register = empty; // P1.register = -1
P1.register = P1.register - 1; // P1.register = -2

P2.register = empty; // P2.register = -1;
P2.register = P2.register - 1; // P2.register = -2

empty = P1.register; // empty = -2
empty = P2.register; // empty = -2

如果正确执行,empty初始值为 -1,P1执行完,empty = -2,P2执行完,empty = -3
上边的例子,empty = -2

所以,信号量empty 需要保护

3.竞争条件

竞争条件:和调度有关的共享数据语义错误
错误是由多个进程并发操作共享数据 引起的
错误和调度顺序有关,很难发现和调试
需要加保护,保证调度的正确执行
有的程序中 会加空循环,减少调度的错误概率,但是不会根本解决调度问题

4.解决竞争条件的直观想法

在写共享变量empty时,给empty上锁, 阻止其他进程访问empty
受保护的 代码段 一次只允许一个进程进入,不能被分割的代码段称为原子操作

//仍然是上边出错的执行序列
P1.register = empty;
P1.register = P1.register - 1;

P2.register = empty;
P2.register = P2.register - 1;

empty = P1.register;
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值