p v操作系统

2018-06-04 23:32:19 hml666888 阅读数 3612

1.互斥:进程A和进程B,要求都进入相同临界资源的临界段CS,下面实现互斥:

semaphor S=1;//定义信号量并确定初值

进程A:

P(S);

CS1;

V(S);

;

进程B:

P(S);

CS2;

V(S);

2.同步:舍友进程A和进程B,要求进程A的输出结果成为进程B的输入信号,即进程B必须在进程A执行完毕之后才能执行

semaphore S=0;

进程A:

V(S);

进程B:

P(S);

信号量S(表示可用资源),当S为负数时,有进程在等待;当S不为负数,则有可用资源。

S的范围:有N个资源,M个进程

1.N>M,N-M表示剩下未用的资源数

2.N<M,S=N-M,|S|表示等待状态的最大进程数

3.N=M,S=N-M,表示所有资源刚好分给了所有进程

4.N>S>0,S表示可用资源数。

2016-11-08 20:20:48 code_AC 阅读数 18943

操作系统之PV操作

今天在做操作系统老师布置的操作系统作业,但是碰到了一个有关pv操作的问题,由于对pv操作的理解不是很透彻,所以我查阅了很多资料,下面来简单的通俗的介绍一下pv操作
1、信号量
  公用信号量:实现进程间的互斥,初值=1或资源的数目
  私用信号量:实现进程间的同步,初值=0或某个整数
2、信号量S的物理意义:S>=0时表示某资源的可用数,s<0时其绝对值表示阻塞队列中等待该资源的进程数。P、V操作是实现进程同步与互斥的常用方法。
3、P操作表示申请一个资源,V操作表示释放一个资源。
P操作的定义:S=S-1,若S>=0,则执行P操作的进程继续执行;若S<0,则置该进程为阻塞状态,并将其插入阻塞队列。
Procedure P(Var S:Semaphore);
Begin
S:=S-1;
If S<0 then w(S) {执行P操作的进程插入等待队列}
End;
V操作定义:S=S+1,若S>0则执行V操作的进程继续执行;若S<0,则从阻塞状态唤醒一个进程,并将其插入就绪队列,执行V操作的进程继续执行。
Procedure V(Var S:Semaphore);
Begin
S:=S+1
If S<=0 then R(s) {从阻塞队列中唤醒一个进程}
End;

利用PV操作实现进程的互斥
令信号量mutex的初值为1,当进入临界区时执行P操作,退出临界区时执行V操作。这样利用PV操作实现进程互斥的代码段如下:
P(mutex)
  临界区
V(mutex)

所以,下面我们来看看这道题,如下图,请用并行语句和P、V操作描述图中任务执行过程。


我写的执行过程是这样的,希望大家多多指教
<span style="font-size:14px;">int f1=0;   //表示进程P1是否执行完毕
int f2=0;   //表示进程P2是否执行完毕
int f3=0;   //表示进程P3是否执行完毕
int f4=0;   //表示进程P4是否执行完毕
int f5=0;   //表示进程P5是否执行完毕
int f6=0;   //表示进程P6是否执行完毕

main()
{
	cobegin
	p1();
	p2();
	p3();
	p4();
	p5();
	p6();
	coend
}

p1(){
	...
	v(f1);
	v(f1);
}
p2(){
	p(f1);
	...
	v(f2);
}
p3(){
	p(f1);
	...
	v(f3);
}
p4(){
	p(f2);
	...
	v(f4);
	v(f4);
}
p5(){
	p(f4);
	...
	v(f5);
}
p6(){
	p(f3);
	p(f4);
	...
	v(f6);
}
p7(){
	p(f5);
	p(f6);
	...
}</span>



p/v操作

2018-03-29 15:33:52 zhoudonghao4381 阅读数 3147

PV操作原语和信号量sem是计算机操作系统进程和线程同步的核心手段,虽然说起来只有句话,但有几个点非常容易引起模糊。先把PV操作的说明如下:

P操作原语:

  1. sem 减1

  2. 若sem 大于等于0,线程继续执行.

  3. 若sem < 0 ,线程进入阻塞队列.

V 操作原语:

  1. sem加1

  2. 若sem 大于 0, 线程继续执行

  3. 若sem 小于等于0,唤醒阻塞队例的线程

问题1.原语概念

    教科书上一般定义是不允许发生中断,一段必须连续执行的指令。在Dijkstra发明原语概念的时代,CPU应该都是单核的,多线程是单个CPU分时间片执行,所有只要是保证是” 连续执行”,就不会发生执行一个线程P操作的sem减1后,另一个线程V操作sem 加1。这意味着可以在现有的程序层面就可以实现多线程的同步而不需要别的指令或硬件。但在现在的多核时代,完全有可能在一个核上执行P操作sem减1后,另一个核上执行V操作sem加1,修改相同的地址空间,从而破坏sem的状态. 这方面.NET和Java都提供了volatile关键字,估计是添加的新的指令来保证,不过还好,这是操作系统操心的事情,操作系统保证原语概念的完整性。

问题2. 信号量

 信号量sem在PV操作里具有三元性质.

让我们来看一个具体的实例: 假设现在的执行场景是有三个线程A,B,C进入一个信号量为1的临界资源,

  1. 当线程A进入时,执行P操作, sem=0,线程A继续执行.

  2. 当线程B进入时,线程A假设仍在占用临界资源, B执行P操作,sem = -1,B进入等待队列。

  3. 当线程C进入时,线程A假设仍在占用临界资源, C执行P操作,sem = -2,C进入等待队列

通过以上的步骤可以发现:

1) 当sem > 0 时,表示可用的临界资源的数量

2) 当sem = 0时,表示无可用的资源,也没有阻塞的线程

3) 当sem <0 时,sem的绝对值表示阻塞队列的线程数

问题3.对V操作2,3步骤的解释

      V操作的第2步,sem > 0 ,线程继续执行.有些人这个地方不解,sem > 0不是代表有资源可用吗?为什么不是唤醒其它的线程。其实正是sem >0 ,sem当前的意义是有资源可用,而没有阻塞的线程,所有根本不需要唤醒.

      V操作的第3步,sem 小于等于0, 唤醒阻塞队例的线程. sem < 0很多人直觉认识都是没资源可用了,干吗还唤醒阻塞队列的线程(包括我)。通过问题2的分析,在这个时候sem代表的是阻塞队列的线程数 ,所以需要唤醒. 让我们接着问题2的步骤.

4) 线程A资源使用完,执行V操作,sem = -1, 唤醒阻塞队列的线程(假设FIFO),B线程进入临界资源开始执行,注意,B不会再执行P操作,因为进入阻塞队列前已执行.P,V操作必须成对执行。

5) B使用完资源后,执行V操作,sem = 0; 唤醒阻塞队列的线程,C线程进入临界资源开始执行,C也不会再执行P操作

6) C使用完资源,执行V操作, sem = 1
转载注明出处:http://blog.sina.com.cn/s/blog_52e214770101ggze.html

2017-03-17 12:15:14 moshenglv 阅读数 6600

知识点:

信号量机制主要有整形信号量、记录性信号量、信号量集机制。

信号量是一个整形变量,根据控制对象的不同赋不同的值。信号量可分为公用信号量和私用信号量两类。

公用信号量:实现进程间的互斥,初值=1或资源的数目

私用信号量:实现进程间的同步,初值=0或某个整数

信号量S的物理意义:S>=0时表示某资源的可用数,s<0时其绝对值表示阻塞队列中等待该资源的进程数。P、V操作是实现进程同步与互斥的常用方法。

P操作表示申请一个资源,V操作表示释放一个资源。

P操作的定义:S=S-1,若S>=0,则执行P操作的进程继续执行;若S<0,则置该进程为阻塞状态,并将其插入阻塞队列。

Procedure P(Var S:Semaphore);

  Begin

   S:=S-1;

   If S<0 then  w(S)   {执行P操作的进程插入等待队列}

  End;

V操作定义:S=S+1,若S>0则执行V操作的进程继续执行;若S<0,则从阻塞状态唤醒一个进程,并将其插入就绪队列,执行V操作的进程继续执行。

  Procedure V(Var S:Semaphore);

     Begin 

S:=S+1

If S<=0 then R(s) {从阻塞队列中唤醒一个进程}

End;

 

利用PV操作实现进程的互斥

 令信号量mutex的初值为1,当进入临界区时执行P操作,退出临界区时执行V操作。这样利用PV操作实现进程互斥的代码段如下:

P(mutex)

  临界区

V(mutex)

 

讨论的习题:

  

信号量与P、V操作
 

 

 

 

 

 

S1初值为2,题目知道有两个发货员我们可以知道用S1表示发货员的数目;同样S2表示审核员的数目。当顾客进程i进入系统,此时为第一个我们有S1=2>0则发货员开始工作P(s1),顾客提完货物以后发货员完成自己的 工作释放资源V(S1);

顾客提完货以后需要检察员进行检测,确认货物是否正确,S2=1>0,则审核员开始工作P(s2) ,

进行检验 ,无论结果如何S2释放资源V(s2)。

所以A,C

 

 

第二个问题:

 

信号量与P、V操作

信号量与P、V操作

信号量与P、V操作
 

当然还有一些知识点需要研究

 

  1。进程间的相互转换

 

  2。同步于互斥、缓冲池

欢迎关注公众号:

2015-03-03 22:33:17 rjlgo 阅读数 11568


可以这样理解:
临界区门前有棵树
用来挂红灯
进程想进CPU的门
先得上树取下盏灯(调用一次P)
取下一个去敲门(S=S-1)
如果树上没有灯取(S<=0)
树说暂时欠你一盏灯(S为负时)
进程没辙只好在门外边排队等(WAIT(S))
得灯的进程继续运行运行完了要出门(调用一次V)
马上还回一盏灯(S=S+1)
若有进程在催债(S<=0)
放个进程进去完成(Release(S))

 

概念难点解析
V原语的主要操作是:

(1)sem加1;

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

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



P操作顺序执行下述两个动作:
①信号量的值减1,即S=S-1;
②如果S≥0,则该进程继续执行;
如果S<0,则把该进程的状态置为阻塞态,把相应的PCB连入该信号量队列的末尾,并放弃处理机,进行等待(直至其它进程在S上执行V操作,把它释放出来为止).
V操作顺序执行下述两个动作:
①S值加1,即S=S+1;
②如果S>0,则该进程继续运行;
如果S≤0,则释放信号量队列上的第一个PCB(即信号量指量指针项所指向的PCB)所对应的进程(把阻塞态改为就绪态),执行V操作的进程继续运行.



典型理解偏差:

一,以V原语的1、2步来做,Sem不就永远大于0,那进程不就一直循环执行成为死循环了?

二,Sem大于0那就表示有临界资源可供使用,为什么不唤醒进程?

三,Sem小于0应该是说没有临界资源可供使用,为什么还要唤醒进程?
析疑:

一,P操作对sem减1的。P、V原语必须成对使用!从而不会造成死循环。

二,Sem大于0的确表示有临界资源可供使用,而且这个时候没有进程被阻塞在这个资源上,也就是说没有进程因为得不到这类资源而阻塞,所以没有被阻塞的进程,自然不需要唤醒。

三,V原语操作的本质在于:一个进程使用完临界资源后,释放临界资源,使Sem加1,以通知其它的进程,这个时候如果Sem<0,表明有进程阻塞在该类资源上,因此要从阻塞队列里唤醒一个进程来“转手”该类资源。

比如,有2个某类资源,三个进程A、B、C、D要用该类资源,最开始Sem=2,当A进入,Sem=1,当B进入Sem=0,表明该类资源刚好用完,

当C进入时Sem=-1,表明有一个进程被阻塞了,D进入,Sem=-2。当A用完该类资源时,进行V操作,Sem=-1,释放该类资源,而这时Sem<0,表明有进程阻塞在该类资源上,于是唤醒一个。
为了进一步加深理解,再引入二个问题:

四,如果是互斥信号量的话,应该设置信号量Sen=1,但是当有5个进程都访问的话,最后在该信号量的链表里会有4个在等待,也是说S=-4,那么第一个进程执行了V操作使S加1,释放了资源,下一个应该能够执行,但唤醒的这个进程在执行P操作时因S〈0 ,也还是执行不了,这是怎么回事呢?

五,Sem的绝对值表示等待的进程数,同时又表示临界资源,这到底是怎么回事?

析疑:

四,当一个进程阻塞了的时候,它已经执行过了P操作,并卡在临界区那个地方。当唤醒它时就立即进入它自己的临界区,并不需要执行P操作了,当执行完了临界区的程序后,就执行V操作。

五,当信号量Sem小于0时,其绝对值表示系统中因请求该类资源而被阻塞的进程数目.S大于0时表示可用的临界资源数。注意在不同情况下所表达的含义不一样。当等于0时,表示刚好用完。

 

★     信号量、PV操作是解决进程间的同步与互斥问题的。

★     做题时尤其要注意隐藏的同步、互斥问题。这些问题通常可以归入生产者-消费者问题和阅读者-写入者问题。

★     PV操作一定是成对出现的,但是这不意味着它会在一个进程内成对出现。

★     在互斥关系中,PV操作一定是在一个进程内成对出现。而且,信号一定大于0,具体多少视情况而定。而对于同步关系,则一对PV操作在两个进程或者更多的进程中出现。

★     对于同步关系,信号量可能为0,也可能不为0;用于同步的信号个数可能1个,也可能是多个。

★     对信号量为1的,应该先执行V操作。

★     在生产者-消费者问题中,要设置三个信号量:empty-空闲的缓存区数量,初值为n;full-已填充的缓存区数量,初值为0;mutex-保证只有一个进程在写入缓存区,初值为1。

★     在阅读者-写入者问题中,设置两个信号量:信号量access-控制写入互斥,初值为1;信号量rc-控制对共享变量ReadCount(读者统计值)的互斥访问。



P:申请一个资源
V:释放一个资源
struct semaphore
{
 int value;//信号量的值,表示可用资源的数目
 List_of_precess L;//在此信号量上等待的进程队列的对手指针
}S;
 if(S.value>0):可供使用的资源的数目
 if(S.value==0):无资源、无进程等待
 if(S.value<0):相反数为等待使用资源的进程的数目
 
 
在信号量上,可建立如下的P、V操作

void P(S)
{
 lock interrupts;//中断
 S.value--;
 if(S.value<0)
 {
  add this process to S.L;
  block;
 }
}
void V(S)
{
 S.value++;
 if(S.value<=0)
 {
  remove a process Pi from S.L;
  unlock(Pi);
 }
}

为了使多个进程互斥地进入各自的同类临界区,可以设置一个互斥信号量,例如mutex,置初始值为1,
并在每一个临界区的前后插入此信号量上的P、V操作,是每个进程有如下结构
void P(int i)
{
 while(true)
 {
  P(mutex);
  critical section;
  V(mutex);
  non-critical section;
 }
}

考虑两个进程P1、P2,P1有程序S1,P2有程序S2。要求设计一个同步方案,使得S1在S2完成以后才执行,为此,
设置一个信号量synch,初始值为0,并使P1、P2有如下形式
void P1()
{
 ...
 P(synch);
 S1;
 ...
}

void P2()
{
 ...
 S2;
 V(synch);
 ...
}


生产者、消费者问题
void main()
{
 int full=0,//满缓冲区的数量
  empty=0,//空缓冲区的数量
  mutex=1,//对有界缓冲区进行操作的互斥信号量
  in=0,
  out=0;
 buffer[n];
 cobegin
  producer();
  consumer();
 coend
}
void prodeucer()
{
 while(true)
 {
  ...
  produce an item in nextp;//生产一件产品
  ...
  P(empty);
  P(metux);
  buffer[in]=nextp;//向缓冲区放一件产品
  in=(++in)%n;
  V(mutex);
  V(full);
 }
}
void consumer()
{
 while(true)
 {
  P(full);
  P(mutex);
  nextc=buffer[out];
  out=(++out)%n;
  V(mutex);
  V(empty);
  consume the item in nextc;
 }
}
在生产者、消费者问题中应该注意:
1、在每个程序中用于实现互斥的P、V操作必须成对出现
2、对资源信号量的操作,同样需要成对的出现,但他们可以处于不同的程序中
3、在每个程序中多个P操作顺序不能颠倒,否则在一定条件下会出现死锁现象



信号量P/V操作

阅读数 1902

P操作和V操作

阅读数 2334