首页 > 代码库 > 【软考】PV操作同步互斥
【软考】PV操作同步互斥
进程
在操作系统中,进程是占有资源的最小单位(线程可以访问其所在进程内的所有资源,但线程本身并不占有资源或仅仅占有一点必须资源),一个进程能有多个线程。
临界资源
指一次只能有一个进程在占用的资源、如现实中的衣服、一件衣服只能一个人在穿、比如一个硬盘、有两个进程对同一块区域进行写操作、数据不就一锅粥了么= =
临界区
在一个进程占有临界资源的时候、别的进程不能占有、这是互斥、从进程占有资源到资源被释放、这一段代码就叫临界区。
临界区原则(有空即进-无空则等-有限等待-让权等待)
个人造词= =
见缝插针:当无进程占用资源、进程可以占用进程(有限时间)
等一会:当有进程占用资源、其他进程就等着
不等了:等了半天那货还不释放资源、饿死我了!不等了
让你们进:进程不能占用此资源、应该释放处理机、让别的进程好占用
解决互斥
为了不让多个进程占用一个资源、每次只保证一个进程占用资源、有一个特别牛掰的人、发明了PV操作和信号量
信号量
信号量分公用信号量和私用信号量
公用信号:
所用进程公有、代表资源的可用数量、一般用S表示
私用信号量:
进程自己可用资源的数量
为什么要有公有信号量和私有信号量?
公有信号量≠私有信号量
有一个桌子、上面放着6个饭盒、女生带走饭盒(空)往里面放饭、男生拿走饭盒(有饭的)、墙上有快黑板、写着桌子上饭盒的数量、男生女生每拿走一个饭盒、都会改一些黑板上的数字、每个女生手机都会动态显示空饭盒的数量、每个男生的手机都会显示有饭的饭盒数量。
解:
进程:男生(消费者)、女生(生产者)
资源:饭盒
公有信号量:黑板上显示桌子上的饭盒数量(包含有饭和没饭的)
私有信号量:
男生手机上饭盒数量(有饭)
女生手机上饭盒数量(空饭盒)
解释:私有信号量是进程可占用的资源数、有饭的男生才能拿来吃、女生刚好相反、所以桌子上的饭盒、不是所有都能被男生进程占用(空的就不行)、不是所有都能被女生进程占用(有饭的就不行)、而黑板上写的是所有在桌子上的饭盒(包括有饭没饭)所以!公有信号量≠私有信号量
PV操作
PV操作是对信号量的操作
P是给信号量减1、V是给信号量+1
P操作的是自己的私有信号量、V是操作的别人的私有信号量、公有信号量每个进程的PV都能操作
PV操作是解决同步互斥问题的
PV操作是一对恋人、有P后面绝对跟着V
例子
我承认、我真的饿了……所以还是拿吃来举例吧……一会搞袋FBM再加个JD…………一想能吃到ZFBMJJD我就流口水…………
咱们继续说上面女生做饭、男生吃的例子、声明下、男生是一个抽象的说法、男生可以有多个、女生也是、当每一个男生的过程如下。
消费者
①改写自己手机上能拿盒饭的数量(其他男生手机上的数也会改)P操作-1
② 要改写黑板上盒饭的数量(桌子上的盒饭数量变了)P操作-1
③拿盒饭、纳尼!没盒饭了!那我在这等着吧(等待)
④吃完了、把空盒子放回去(释放资源)
⑤改写黑板上的数字 V操作+1
⑥改写女生手机上的空盒饭盒子数 V操作+1
女生的此处略……要不一会就饿死了我
由上面可知、男生只要关注自己的手机、就可知道可使用资源的数量、女生也如此、但是他们都很白痴、到了桌子那写完黑板、改完手机、才发现可用资源<0了、所以就在那等待喽……
PV操作过程
解释:
抱歉额、解释一下、饭盒是不能拿走、我犯了一个错误、为了真实性就不改上面的字了、饭盒应该是不能被拿走的、女生只能把做好的饭带过来放进饭盒、男生只能把饭拿走(甭管方法、手抓!)、当放饭和拿走饭的时候、算是占用饭盒!黑板上写的是没有被男生和女生占用的饭盒……这样看上面的图就懂了吧…………男生是拿走了之后不用盒子了、所以做了两个V操作、然后吃饭、画个图发现自己把自己撂里面了……
PV代码
(P方法和V方法、操作流程就不写了)
<span style="font-size:18px;">import java.util.concurrent.Semaphore; /** * 抽象任务,具体的执行任务,归实现类负责 * * @author Administrator * */ public abstract class Task { public abstract void run(); private Semaphore s; private boolean hasExisted = false; public void P(final Semaphore s) throws InterruptedException { if (s == null) { // 申请空的信号量 throw new InterruptedException("不能为空"); } if (hasExisted) {// 已经申请了一个资源,还没有释放 throw new InterruptedException("已经占用一个资源"); } s.acquire();// 阻塞 this.s = s; hasExisted = true; } public boolean V() { if (!hasExisted) { return false;// 没沾有资源就不能说释放了 } s.release();//释放资源 hasExisted = false; s = null; return true; } }</span>
阻塞
是指消费者(男生)在消费的时候、S2<0的时候、S<0的时候、就会阻塞、因为是先减的、所以会为负数、就好像男生在排队、手机上和黑板上都会为 —3。
PV的问题
1 难度大、使用不当易引起死锁
2 效率底、如男生女生每次只能拿放一盒饭的饭
总结:
私有信号量其实就是进程本身能用的资源量、公有信号量其实就是个个进程未占用的资源数量、消费者的私有信号量+生产者的私有信号量=公有信号量、P操作表示申请一个资源、V操作表示释放一个资源、按照上面的说就是:
男:
我在拿饭的时候S=S-1(桌子上没被男女占用的饭盒减1)、S2=S2-1(因为把饭拿走了、男生能拿走饭的数量减1)
饭拿完了S=S+1(桌子上没被男女占用的饭盒+1)、S1=S1+1(女生能装饭的盒子+1)
女生:
放饭的时候 S=S-1(桌子上没被男女占用的饭盒减1)、S1=S1-1(因为把饭装满了、女生能装满的饭盒子数量减1)
饭放好了了S=S+1(桌子上没被男女占用的饭盒+1)、S2=S2+1(男生能吃的有饭的盒饭+1)
写了2个多小时= =我去……2014年10月10日1:15:44
这句话没看懂吧!
我承认、我真的饿了……所以还是拿吃来举例吧……一会搞袋FBM再加个JD…………一想能吃到ZFBMJJD我就流口水…………
翻译
我承认、我真的饿了……所以还是拿吃来举例吧……一会搞袋 方便面 再加个鸡蛋…………一想能吃到 煮方便面加鸡蛋 我就流口水…………
——————————————吃饱睡觉(~﹃~)~zZ——————————————
——————————chenchen———————————
【软考】PV操作同步互斥