同步与互斥pv购票系统c语言,【软考】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操作过程

0818b9ca8b590ca3270a3433284dd417.png

解释:

抱歉额、解释一下、饭盒是不能拿走、我犯了一个错误、为了真实性就不改上面的字了、饭盒应该是不能被拿走的、女生只能把做好的饭带过来放进饭盒、男生只能把饭拿走(甭管方法、手抓!)、当放饭和拿走饭的时候、算是占用饭盒!黑板上写的是没有被男生和女生占用的饭盒……这样看上面的图就懂了吧…………男生是拿走了之后不用盒子了、所以做了两个V操作、然后吃饭、画个图发现自己把自己撂里面了……

PV代码

(P方法和V方法、操作流程就不写了)

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;

}

}

阻塞

是指消费者(男生)在消费的时候、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———————————

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值