Linux-03-PV

Linux-03-PV

1. 疑惑解答

  • 进程通常分为就绪、运行和阻塞三个工作状态。三种状态在某些条件下可以转换,三者之间的转换关系如下:

mark

进程三个状态之间的转换就是靠PV操作来控制的。

PV操作主要就是P操作、V操作和信号量。其中信号量起到了至关重要的作用。

信号量

信号量是最早出现的用来解决进程同步与互斥问题的机制。 

  • 信号量由一个值和一个指针组成,指针指向等待该信号量的进程。信号量的值表示相应资源的使用情况。
  • 信号量S>=0时,S表示可用资源的数量。执行一次P操作意味着请求分配一个资源,因此S的值减1;
  • S<0时,表示已经没有可用资源,S的绝对值表示当前等待该资源的进程数。请求者必须等待其他进程释放该类资源,才能继续运行。而执行一个V操作意味着释放一个资源,因此S的值加1;
  • 若S<0,表示有某些进程正在等待该资源,因此要唤醒一个等待状态的进程,使之运行下去。

注意,信号量的值只能由PV操作来改变。

\关于PV操作容易产生的一些疑问:**

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

  • S大于0的确表示有临界资源可供使用,也就是说这个时候没有进程被阻塞在这个资源上,所以不需要唤醒。

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

  • V原语操作的本质在于:一个进程使用完临界资源后,释放临界资源,使S加1,以通知其它的进程,这个时候如果S<0,表明有进程阻塞在该类资源上,因此要从阻塞队列里唤醒一个进程来“转手”该类资源。
  • 比如,有两个某类资源,四个进程A、B、C、D要用该类资源,最开始S=2,当A进入,S=1,当B进入S=0,表明该类资源刚好用完, 当C进入时S=-1,表明有一个进程被阻塞了,D进入,S=-2。当A用完该类资源时,进行V操作,S=-1,释放该类资源,因为S<0,表明有进程阻塞在该类资源上,于是唤醒一个。

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

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

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

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

2. 临界区和临界资源

  1. 临界区
  • 每个进程中访问临界资源的那段程序代码称为临界区
  • 每次只准许一个进程进入临界区,进入后不允许其他进程进入。
  1. 临界资源
  • 临界资源是一次仅允许一个进程使用的共享资源
  1. 进程进入临界区的调度原则是:
  • 如果有若干进程要求进入空闲的临界区,一次仅允许一个进程进入
  • 任何时候,处于临界区内的进程不可多于一个。如已有进程进入自己的临界区,则其它所有试图进入临界区的进程必须等待。
  • 进入临界区的进程要在有限时间内退出,以便其它进程能及时进入自己的临界区
  • 如果进程不能进入自己的临界区,则应让出CPU,避免进程出现“忙等”现象。

3. PV操作

临界区:我们把并发进程中与共享变量有关的程序段称为临界区。

信号量S

  • 信号量的值与相应资源的使用情况有关。当它的值大于0时,表示当前可用资源的数量;
  • 当它的值小于0时,其绝对值表示等待使用该资源的进程个数。

P操作P(S):将信号量S减去1,若结果小于0,则把调用P(S)的进程置成等待信号量S的状态。即为请求资源。

V操作V(S):将信号量S加上1,若结果不大于0,则释放一个等待信号量S的进程。即为释放资源。

正如老师上课时所举的父亲给孩子吃苹果的例子一样,假如一个盘子只能放一个苹果,父亲往盘子里放了一个苹果。如果儿子吃了(V操作),父亲才可以接着放(P操作);如果儿子不吃,那父亲就不能放苹果,只能等着。

伪代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Procedure P (Var S:Semaphore)

begin

S:=S - 1;

if S<0 then W(S)

end; { P }



Procedure V (Var S:Semaphore)

begin

S:=S + 1;

if S< = 0 then R(S)

end; { V }

# W(S):表示把调用P(S)的进程置成等待信号量S的状态。
# R(S):表示释放一个等待信号量S的进程。

3.1 进程互斥

1
2
3
4
5
6
7
    利用信号量和PV操作实现进程互斥的一般模型是:
进程P1 进程P2 …… 进程Pn
…… …… ……
P(S); P(S); P(S);
临界区; 临界区; 临界区;
V(S); V(S); V(S);
…… …… …… ……
其中信号量S用于互斥,初值为1。
使用PV操作实现进程互斥时应该注意的是:
(1)每个程序中用户实现互斥的P、V操作必须成对出现,先做P操作,进临界区,后做V操作,出临界区。若有多个分支,要认真检查其成对性。
(2)P、V操作应分别紧靠临界区的头尾部,临界区的代码应尽可能短,不能有死循环。
(3)互斥信号量的初值一般为1。

3.2 进程同步

1
2
3
4
5
6
7
8
利用信号量和PV操作实现进程同步
PV操作是典型的同步机制之一。用一个信号量与一个消息联系起来,当信号量的值为0时,表示期望的消息尚未产生;当信号量的值非0时,表示期望的消息已经存在。用PV操作实现进程同步时,调用P操作测试消息是否到达,调用V操作发送消息。

使用PV操作实现进程同步时应该注意的是:

(1)分析进程间的制约关系,确定信号量种类。在保持进程间有正确的同步关系情况下,哪个进程先执行,哪些进程后执行,彼此间通过什么资源(信号量)进行协调,从而明确要设置哪些信号量。
(2)信号量的初值与相应资源的数量有关,也与P、V操作在程序代码中出现的位置有关。
(3)同一信号量的P、V操作要成对出现,但它们分别在不同的进程代码中。
打赏
  • 版权声明: 本博客所有文章除特别声明外,均采用 Apache License 2.0 许可协议。转载请注明出处!
  • © 2019-2022 Zhuuu
  • PV: UV:

请我喝杯咖啡吧~

支付宝
微信