关于P,V操作理解的分析

 

P-V操作定义:

假设sem是个整型变量。
P原语的主要操作是:

1sem1

2)若sem1后仍大于或等于零,则该进程继续执行;

3)若sem1后小于零,则该进程被阻塞,在相应队列中排队,然后转向系统的进程调度。

V原语的主要操作是:

1sem1

2)若相加结果大于零,则进程继续执行;

3)若相加结果小于或等于零,则唤醒一阻塞在该信号量上的进程,然后再返回原进程继续执行或转进程调度。

 
我原先对于PV操作的概念很模糊,就知道  P操作是减法运算(S:=S-1),当信号量S小于0时申请资源;V操作是加法运算(S:=+1),当信号量小于等于0时释放资源;P、V操作二者必须成对出现。
但是关于具体含义,我是一点也不清楚。但是昨晚经过我们讨论后,我对其中原理的理解渐渐的就理解了,但是同样往更深层次的理解要求也就更深了,我这样,别人也一样!
这就是为什么后来小组讨论进入了最后一个也是最有争议的一点(只要明白了这一点,PV操作就全部明白了),如下图:
PV操作到底为何?
【b1:V(S1);b2:P(S2);c1:P(S1);c2:V(S2);S1=0;S2=0】
争议的地方是:执行到V(S1)时,唤醒收银员进程执行P(S1),那么此时顾客进程是否还继续执行呢?换句换说唤醒收银员进程到底是怎么唤醒的。
其实我认为最为正确的PV原理解释是(如果有不对的地方可以及时提出):
顾客进程与收银员进程由于是同步关系,所以二者进程其实在一开始就并发执行,收银员进程执行到P(S1)时,由于S=S-1,S1得-1,所以等待,顾客进程执行到V(S1)时此时由于S1为-1,经S=S+1计算S1为0,所以唤醒收银员进程P(S1),此时顾客进程是继续进行的,执行到P(S2)时,S2经计算得-1,所以等待,收银员进程执行到V(S2)时,S2经计算得0,所以唤醒顾客进程,收银员进程继续执行,执行到P(S1)时,由于S1经计算得-1,所以等待,而此时顾客进程执行完毕离开超市。
其实蓝字部分还有一种可能,就是唤醒收银员进程后,收银员进程首先进行到V(S2)【比顾客进程到达P(S2)早】,其实最终结果是不会变的,V(S2)经过计算此时为1,所以继续执行,执行到P(S1),可此S1经计算为-1,所以等待,而顾客进程执行到P(S2)时,S2经过计算为0,所以继续执行,最终离开超市。
通过以上我们可以看出,站在不同角度分析,就会有多种解释的方法,这也是造成我们产生歧义的主要原因,就是谁说的都对,最终结果都一样,但是到底谁才是真理呢?我猜想,大家的猜想是把所有的可能都包含在内了,但是我们不明白,所以总认为有一方是错的,其实谁的解释都是正确的。
基本类型的变量如果是临时变量,只要定义了,就会分配内存空间,不管是否被赋值;如果是作为对象的属性出现,只要该对象不实例化,就不会分配内存空间。

一个完整的Java程序运行过程会涉及以下内存区域:
1、寄存器:JVM内部虚拟寄存器,存取速度非常快,程序不可控制。
2、 栈:保存局部变量的值,包括:
1)用来保存基本数据类型的值;
2)保存类的实例,即堆区对象的引用(指针)
3)也可以用来保存加载方法时的帧
3、堆:用来存放动态产生的数据,比如new出来的对象。注意创建出来的对象只包含属于各自的成员变量,并不包括成员方法。因为同一个类的对象拥有各自的成员变量,存储在各自的堆中,但是他们共享该类的方法,并不是每创建一个对象就把成员方法复制一次。

4、常量池:JVM为每个已加载的类型维护一个常量池,常量池就是这个类型用到的常量的一个有序集合。包括直接常量(基本类型,String)和对其他类型、方法、字段的符号引用(1)。池中的数据和数组一样通过索引访问。由于常量池包含了一个类型所有的对其他类型、方法、字段的符号引用,所以常量池在Java的动态链接中起了核心作用。常量池存在于堆中。

5、代码段:用来存放从硬盘上读取的源程序代码。
6、数据段:用来存放static定义的静态成员
posted @ 2016-11-01 08:08  狡啮之仰  阅读(3067)  评论(0编辑  收藏  举报