PV原语的应用
PV原语可以解决进程管理当中的互斥问题,以及同步问题,还有通信问题.
我觉得我只要明白互斥和同步问题就好了,通信就…
(1)用PV原语实现进程互斥
把临界区置于P(sem) 和V(sem)之间。(PS:信号量的英文是semaphore)
当一个进程想要进入临界区时,它必须先执行P操作以将信号量sem减1,在进程完成对临界区的操作后,它必须执行V操作以释放它所占用的临界区。从而就实现了进程的互斥:
我的理解:
互斥的概念就我自己的理解就是,2个进程或多个进程要使用同一个资源,而且他们同时都想使用,但是这个资源他们谁都能用,但是一次只能给一个进程用,那么这些个进程之间的关系就是互斥的.你用了资源,我就用不了.(理解不对,欢迎指教)
还有临界区的概念,在我看来,就是下面这段代码.进去先P,出来就V,中间执行.
(理解不对,欢迎指教)
理解错误
临界区指的是上图中P(sem)和V(sem)中间的<S>.进入临界区<S>之前需要P操作,出来需要V操作.
还有就是互斥,不是指的进程之间的关系是互斥,而是对临界资源来说,是互斥的,这个概念我自己也没有太理解,就这样吧.
然后上面提到的具体的过程我们可以简单的描述如下:
PA: P(sem) <S>; V(sem) | PB: P(sem) <S>; V(sem) |
解析:
由于互斥,只有一个资源,所以sem信号量就只有一个
PA,PB各是一个进程,他们是互斥的关系.要么PA占着资源,PB用不了,PB只能等着PA释放资源;要么PB占着资源,PA用不了,PA等着PB释放资源.
sem的初值为1,表示有一个资源.PA和PB是可以同时操作的,但是资源只有一个,看系统把资源分配给谁了.这里假设PA运气好,系统看它人品好,把资源给了他.
PA,P(sem),sem=sem-1=1-1=0,然后PA就开始咔咔咔工作.
与此同时,进程PB 也跟系统说,给一个资源吧,但是系统偏心,资源已经给了PA了.它P(sem)一下,发现sem=sem-1=0-1=-1,木有资源了,只能等着了.
然后PA咔咔咔工作完了之后,V(sem)一下,释放资源,sem=sem+1=-1+1=0,<=0,所以唤醒一个在等着的进程,PB就被唤醒了.
然后由于PB之前已经P(sem)过了,不用再P(sem)了,直接开始咔咔咔工作,工作完了走的时候也释放了资源,V(sem),sem=sem+1=0+1=1,又有一个资源了.
至此互斥整完了,整同步.
(2)用PV原语实现进程同步
假设两个进程需要同步进行,一个进程是计算进程,另一个进程是打印进程,那么这个时候两个进程的定义可以表示为:
我的理解:
同步就是2个进程协同完成一个工作.(某人说也可以是多个进程,不能理解啊)比如小A 和小B,要他俩同时到达一个地方拿东西,他俩都到了,东西才能给他们.但是他俩不一定要同时从同一个地方出发,他们可以在任意时间,任意地点出发,而且他们的速度还不要求一致,但是或许在路上,或许在终点,先到的得等着后到的,才能完成这个工作.
或者举消费者和生产者的例子,消费者只会消费东西,生产者只会生产东西,他们有个盛东西的筐,筐是有容量的,生产者生产的比消费者消费的多,那么筐会满,满了,生产者就要停下来等消费者消费.消费者消费的比生产者生产的快,那么筐会空,空了,消费者就要停下来等生产者生产.
他们的工作就是生产者生产东西,消费者消费东西.他们要协作才能完成这个工作,要不然只有生产者生产东西,筐满了,这个工作也继续不下去了,就停了.或者只有消费者消费东西,没有生产者,消费什么.
所以,我理解的同步就是进程协作完成工作,他们不用抢一个资源(互斥). (理解不对,欢迎指教)
我的理解结束了,继续结合上面理解同步的PV原语.
这个应该是伪代码部分.
主要功能计算进程计算完了结果,打印进程将结果打印出来.
PC(表示计算进程) A: local buf repeat buf=buf until buf=空 计算 得到计算结果 buf=计算结果 goto A | PP:(表示打印进程) B: local pri repeat pri=buf until pri!=空 打印buf中的数据 清除buf中的数据 goto B |
我的解析:
从PC这边看,从上到下,意思大概是,有一个buf(buffer,缓冲区,我觉得在这里它是一个变量)用来存储计算的结果.repeat不知道是什么,buf=buf,是赋值,但是不明白,untilbuf=空,等着buf变成空的,才开始计算,计算得到了结果,把结果赋给buf,然后再来一次A操作,gotoA.
从PP打印进程这边看,有一个pri,也应该是个变量.repeat,是刷新吗,依旧不懂.pri=buf,把buf中的结果给pri,until pri !=空,只要pri不是空的,就打印buf中的数据,打印完了清空,然后goto B继续执行B
总述:能明白大概的意思,部分代码不理解.以后理解了,再补.
相应用P,V的实现过程为:
我的理解:
首先对于这里面的一些东西进行下说明.Deposit(data)是计算进程,remove(data)是打印进程.bufempty是计算进程的私用信号量,空着的缓冲区有n个.buffull是打印进程的私用信号量,初值是0,表示满着的缓冲区为0个.
PA: deposit(data) Begin local x P(bufempty) 按FIFO方式选择一个空缓冲区buf(x) buf(x)=data buf(x) 置满标记 V(buffull) end | PB: remove(data) Begin local x P(buffull) 按FIFO方式选择一个装满数据的缓冲区buf(x) data=buf(x) buf(x)置空标记 V(bufempty) end |
我的解析:
从PA端开始理解,大体和上面一样,不是很懂,只能说明部分意思.
一开始PA先是存储有一个data数据,在计算之前,P(bufempty)一下,给n个空的buf申请资源,要占一个地.P(bufempty)=bufempty-1=n-1>0,所以有地.把准备好的数据data放在用FIFO(先进先出)的方式选出的一个空缓冲区中(这说明可用的缓冲区挺多,还要选),然后buf(x)标记下这个缓冲区被占了,不能再被用了.V(buffull)=buffull+1=0+1=1>0,PB可以开始打印了.
PB P(buffull),申请资源,要打印一个满的缓冲区中的数据.P(buffull)=buffull-1=1-1=0>=0,可以打印.打印谁还是用FIFO的方式决定,然后把缓冲区中的数据赋给data,buf(x)的数据用完了,缓冲区设置为空,V(bufempty),释放了这个缓冲区资源了.
(3)用P V实现进程通信
我们以邮箱通信为例说明问题:
邮箱通信满足的条件是:
<1>发送进程发送消息的时候,邮箱中至少要有一个空格能存放该消息。
<2>接收进程接收消息时,邮箱中至少要有一个消息存在。
发送进程和接收进程我们可以进行如下的描述:
Deposit(m)为发送进程,接收进程是remove(m). fromnum为发送进程的私用信号量,信箱空格数n。mesnum为接收进程的私用信号量,初值为0.
Deposit(m): Begin local x P(fromnum) 选择空格x 将消息m放入空格x中 置格x的标志为满 V(mesnum) end | Remove(m) Begin local x P(mesnum) 选择满格x 把满格x中的消息取出放m中 置格x标志为空 V(fromnum) end |
PS:这个的挺好懂的,就不分析了.