Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3976293
  • 博文数量: 408
  • 博客积分: 10227
  • 博客等级: 上将
  • 技术积分: 9820
  • 用 户 组: 普通用户
  • 注册时间: 2009-04-17 21:48
个人简介

非淡泊无以明志,非宁静无以致远

文章存档

2022年(1)

2021年(1)

2020年(2)

2019年(5)

2018年(4)

2017年(3)

2016年(24)

2015年(8)

2014年(7)

2013年(3)

2012年(1)

2011年(23)

2010年(179)

2009年(147)

分类:

2009-11-26 10:44:33

1.PV原语的含义

     P操作和V操作是不可中断的程序段,称为原语。PV原语及信号量的概念都是由荷兰科学家E.W.Dijkstra提出的, 其基本思路是用一种新的变量类型(semaphore)来记录当前可用资源的数量。信号量sem是一整数,sem大于等于零时代表可供并发进程使用的资源实体数,但sem小于零时则表示正在等待使用临界区的进程数。

P原语:P是荷兰语Proberen(测试)的首字母。为阻塞原语,负责把当前进程由运行状态转换为阻塞状态,直到另外一个进程唤醒它。操作为:申请一个空闲资源(把信号量减1),若成功,则退出;若失败,则该进程被阻塞;P原语操作的动作是:

1 sem1

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

3 sem1后小于零,则该进程被阻塞后进入与该信号相对应的队列中,然后转进程调度。

V原语:V是荷兰语Verhogen(增加)的首字母。为唤醒原语,负责把一个被阻塞的进程唤醒,它有一个参数表,存放着等待被唤醒的进程信息。操作为:释放一个被占用的资源(把信号量加1),如果发现有被阻塞的进程,则选择一个唤醒之。V原语操作的动作是:

1 sem1

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

3 若相加结果小于或等于零,则从该信号的等待队列中唤醒一等待进程,然后再返回原进程继续执行或转进程调度。

     PV操作对于每一个进程来说,都只能进行一次,而且必须成对使用。在PV原语执行期间不允许有中断的发生。

信号量是由操作系统来维护的,用户进程只能通过初始化和两个标准原语(PV原语)来访问。初始化可指定一个非负整数,即空闲资源总数。

 

2.分类:

具体PV原语对信号量的操作可以分为三种情况:

1)把信号量视为一个加锁标志位,实现对一个共享变量的互斥访问。

实现过程:

P(mutex);           // mutex的初始值为1

访问该共享数据;

V(mutex);

非临界区

2)把信号量视为是某种类型的共享资源的剩余个数,实现对一类共享资源的访问。

实现过程:

P(resource);          // resource的初始值为该资源的个数N

使用该资源;

V(resource);

非临界区

3)把信号量作为进程间的同步工具

实现过程:

临界区C1    P(S);

V(S);           临界区C2

需要提醒大家一点就是P,V操作对于每一个进程来说,都只能进行一次。而且必须成对使用。且在P,V愿语执行期间不允许有中断的发生。

对于具体的实现,方法非常多,可以用硬件实现,也可以用软件实现。我们采用如下的定义:

    procedure p(var s:samephore);

      {

        s.value=s.value-1;

        if (s.value<0) asleep(s.queue);

      }

   procedure v(var s:samephore);

      {

        s.value=s.value+1;

        if (s.value<=0) wakeup(s.queue);

      }

其中用到两个标准过程:

asleep(s.queue);执行此操作的进程控制块进入s.queue尾部,进程变成等待状态

wakeup(s.queue);s.queue头进程唤醒插入就绪队列

对于这个过程,s.value初值为1时,用来实现进程的互斥。

虽然说信号量机制比加锁方法要好得多,但是也不是说它没有任何的缺陷。由此我们也可以清晰地看到,这种信号量机制必须有公共内存,不能用于分布式操作系统,这是它最大的弱点。

阅读(2071) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~