您的位置:首页 > 其它

操作系统的信号量 进程互斥 同步等概念

2015-03-23 08:39 369 查看
摘 要:
本文针对目前操作系统中利用信号量解决进程间的同步和互斥的问题,系统地总结了解决问题的一般性规律。首先介绍了信号量的定义及在信号量上可以执行的两个操作,并分别详细说明了如何利用信号量实现进程间的同步和互斥,最后结合实例说明了这两种方法在实际问题中的具体运用。

在多道程序环境下,操作系统如何实现进程之间的同步和互斥显得极为重要。荷兰学者Dijkstra给出了一种解决并发进程间互斥与同步关系的通用方法,即信号量机制。他定义了一种名为“信号量”的变量,并且规定在这种变量上只能做所谓的P
操作和 V操作。现在,信号量机制已经被广泛地应用于单处理机和多处理机系统以及计算机网络中,这也是学习操作系统的重点和难点之一。本

文就利用信号量实现进程间的同步和互斥问题进行了分析。

1引言

信号量是一个具有非负初值的整型变量,并且有一个队列与它关联。(队列存放关于该信号量的阻塞进程)因此,定义一个信号量时,要给出它的初值,并给出与它相关的队列指针。信号量除初始化外,仅能通过P、V
两个操作来访问,这两个操作都由原语组成,即在执行过程中不可被中断,也就是说,当一个进程在修改某个信号量时, 没有其他进程可同时对该信号量进行修改。

P(S)操作可描述为:

信号量的定义如下:
type semaphore=record
/*定义信号量*/
begin
value:integer;  /*整型变量*/
L:list of process;
/*与该信号量相关联的队列*/
end
P(S) 操作可描述为:
procedure P(S)
var S: semaphore;
begin
S.value:=S.value-1;
/*信号量的值减 1*/
if S.value<0 then block(S,L)
/*若信号量的值小于 0,则阻塞执行该 P 操作的进程*/
end
当执行
P(S)操作时,信号量S的值减
1,如果S≥0,表示可以继续执行;如果S<0,表示该进程只能进入S信号量的阻塞队列中等待,由调度程序重新调度其他进程执行。需要注意的是,使该信号量S的值增加的进程会将该阻塞进程唤醒,该进程一旦获得处理机,就可以直接进入临界区,无需再执行
P(S)操作。

V(S)操作可描述为:

procedure V(S)
var S: semaphore;
begin
S.value:=S.value+1;
if S.value≤0
then wakeup(S,L) ;
end


当执行 V(S)操作时,信号量S的值加
1,如果S≤0,则唤醒S信号量阻塞队列队首的阻塞进程,将其状态从阻塞状态转变为就绪状态,执行V操作的进程继续执行;如果S>0,则说明没有进程在该信号量的阻塞队列当中,因此,无需唤醒其他进程,该进程继续执行。

总结:P操作相当于要占有临界资源,因为资源是多进程共享的,所以当s<0时,表明,临界资源已经被占用完,必须要等待其他进程释放临界资源,所以,执行P操作(申请临界资源的操作)要进入对应该信号量(一个信号量标志了一个临界资源)的阻塞队列中。

执行V操作,相当于释放资源,如果s<=0,说明临界资源还是被其他进程所占用,那么就将该信号量的阻塞队列的队首进程唤醒,由阻塞状态变为就绪状态。如果s>0,说明还是临界资源还没被占用完,即阻塞队列为空,无需唤醒其他进程,该进程继续执行。

2利用信号量实现进程互斥

利用信号量实现进程互斥的进程可描述如下:

Var s:semaphore:=1;
/*设置信号量 s 的初值为 1*/
begin
parbegin /*并发开始*/
process1:
begin
repeat
P(s) ;
critical section
V(s) ;
remainder section
until false;
end
process2:
begin
repeat
P(s) ;
critical section
V(s) ;
remainder section
until false;
end
parend
end


以 上 描 述 的 是 并 发 执 行 的 两 个 进 程
process1 和process2,这两个进程的临界区(critical section)对应的是一个临界资源,为了保证这两个进程能够互斥地使用临界资源,在每个进程的临界区前后分别加上对同一个信号量的P操作和
V操作,就好象分别是关锁和开锁操作一样。我们将该信号量的初值设为1,无论哪一个进程先获得处理机,在进入临界区之前都要进行P
操作,执行
P操作后,信号量
s
的值为 0,该进程可以继续执行;若该进程在临界区内失去处理机,而由另一个进程获得处理机执行时,执行的进程在进入临界区之前执行P
操作时,信号量
s的值就为-1,此时该进程就得阻塞,进入到信号量s
的等待队列当中等待;当在临界区内的进程再次获得处理机继续执行后,退出临界区时,执行V
操作,信号量
s的值为
0,此时它要去唤醒阻塞进程,然后继续执行或转进程调度。需要注意的是,使该信号量 S 的值增加的进程会将该阻塞进程唤醒,该阻塞进程一旦获得处理机,就可以直接进入临界区,无需再执行 P(S)操作。 用信号量实现进程互斥的特点:

(1)要找对临界区,范围小了会出错,范围大了会影响进程运行。

(2) P、V
操作位于临界区前后,在一个进程里成对出现。

(3) 2
个进程对 1
个临界资源互斥使用时信号量初值为 1,取值范围为-1,0,
1。

(4)
当 n
个进程要互斥使用 m
个同类临界资源时(n>m),用信号量实现互斥时,信号量的初值应为m,即该类可用资源的数 目。信号量的取值范围为-(n-m)~m。

(5)
当信号量 s<0时,
|s|为等待该资源的进程的个数;即因该资源而阻塞的阻塞队列中进程个数。

(6)
当信号量 s>0时,
s表示还允许进入临界区的进程数,即剩下的临界资源个数)。

(7)
执行一次 P(s)操作,表示请求一个临界资源,s-1后,当s<0
时,表示可用资源没有了,进程阻塞。

3利用信号量实现进程同步

可以通过一个例子来说明进程同步的实现。

例如,有一个缓冲区,某一个时刻只能存一个数据,计算进程 P1
将计算出的结果放入缓冲区,输出进程 P2
往外取数据输出,进程 P1
一旦放入数据后,必须等进程 P2取出数据以后它才能继续往里放,否则会导致前一次放入的数据丢失;进程P2
取出数据后,必须等进程P1
放入下一个数据后它才能够继续取,否则会导致两次取出的是同一个数据。可见,这是一个典型的进程同步关系,进程P1和
P2 在协调着共同完成一个任务。

解决这个同步问题的进程描述如下:

Var s1,s2:semaphore:=0,0;
begin
parbegin
P1:
begin
repeat
获得数据;
计算;
送至缓冲区;
V(s1) ;
P(s2) ;
until false;
end
P2:
begin
repeat
P(s1) ;
从缓冲区中取数据;
输出;
V(s2) ;
until false;
end
parend
end
以上实现的是两个并发进程P1和
P2的同步关系。这里设了两个信号量s1和
s2,分别是两个进程用来进行相应的消息传递以便来实现同步的,一般实现同步的信号量的初值可以设为0。因为必须先计算,后输出,所以P1
进程的执行要先于P2。如果P2先获得处理机,则
P2
要先执行一个
P(s1)操作,由于s1的初值为
0,所以执行P(s1)后,P2会阻塞;
P1
获得处理机后可以一直执行,当放完数据以后,它要执行V(s1),即看一下是否有进程在信号量s1的队列中等待,若有,它要去唤醒;然后,为了防止P1继续往缓冲区中放数据,在执行V(s1)操作之后,马上又执行P(s2),随即阻塞,
直等到 P2
取完数据输出后执行 V(s2)

将其唤醒。

用信号量实现进程同步的特点:

(1)
配对的 P、V
操作分别在不同的进程里。有的时候P操作和
V操作的个数并不相等。

(2)
初值一般为 0,需要设一个以上的信号量(例如2个进程同步,需要设2
个信号量,分别用来传递信息)。

(3)
在实现进程同步时,需要分析哪个进程不可以先执行,在不允许直接进行的操作前面加上 P操作来进行条件限制。并在使其操作成为可能的其他进程的操作后面加上对同一个信号量的V
操作。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: