老娘不能同时被强奸(共享资源竞争问题)
问题描述:X=10,A操作将其增加20,B操作将其减少10;
A读取:10
B读取:10
A写入:10+20 = 30
B写入:10-10 = 0
最终结果0(这是强奸后的结果)。
解决方案:进门请上锁(用锁)
1.锁信息放在公用的存储空间:比如说redis
2.锁必须有唯一标识(能唯一映射所锁定的资源)
3.锁状态status=0,打开;status=1,锁定
接下来,排队进入吧
假如有P1、P2、P3准备潜入。
P1进入前:获取该房门的锁,
P1进入:锁上房门status=1(此时P2、P3在后面排队中)
P1完事:打开锁
接下来.....P2...P3.....
那么问题来了:
1.万一P1这孩子在里面啪啪啪猝死了怎么办?(这房门是不是永远被锁住了)
2.假如P1、P2同时到达房门,两人发现锁都是打开的(因为这儿的判断锁状态是分为读取和判断两步,这两步不具备原子性)。
另外再高级点:
如果这个场景中引入一个第三者:医生。医生负责检查娘们儿是否健康;而检查流程是:进入房门->上锁->检查->开锁->走人
那么P1进入的过程就变成:
P1获取该房门的锁,
P1进入,锁上房门
P1呼叫医生
医生进入房门
医生上锁
医生检查
医生开锁
医生走人
P1啪啪
.......
注意这个过程,1、房门被P1锁上的,医生进入还能继续锁门,2、医生走人前开锁,尼玛,开锁会不会把别的汉子也放进来?这个问题叫“可重入锁”
其次
一般使用锁保持数据的一致性,都不会像我上面描述的一样,房门被锁上之后进行排队。通常情况下是发现房门被锁了,老子就在门口睡觉;这儿有两个问题:
1、如果说睡觉的汉子每隔10分钟醒一次,有可能会造成某段时间房门没有被锁,也没有汉子进去啪啪啪,资源浪费了。
2、如果说门锁打开会通知门口睡觉的汉子,会不会叫醒一堆然后蜂拥而上,饥渴难耐啊(Herd Effect,惊群效应)。
3、如果不用排队了,就可能造成不公平(后来的先进去),没有按照竞争者按顺序获得锁(公平锁和非公平锁问题)。
OK,开个怡红院也不容易。
这是个坑,
[坑]
请自行解决.......