DJ2-4 进程同步(第二节课)
创始人
2025-06-01 03:54:16
0

目录

2.4.3 信号量机制

1. 整型信号量

2. 记录型信号量

3. AND 型信号量

4. 信号量集

三种特例

2.4.4 信号量的应用

1. 利用信号量实现进程互斥

2. 利用信号量实现前趋关系

2.4.5 管程机制

1. 管程的组成

2. 管程的主要特点


2.4.3 信号量机制

信号量(Semaphores)机制:是一种卓有成效的进程同步工具。

1. 整型信号量

把整型信号量定义为一个用于表示资源数目的整型量 S,仅能通过两个标准的原子操作 wait(S) 和 signal(S) 来访问。这两个原子操作又分别被称为 P 和 V 操作,注意必须使用大写。

wait(S) {while(S <= 0);  //do no-op,CPU空转S--;            //访问资源,资源减一
}signal(S) {S++;            //释放资源,资源加一
}

在 wait(S) 中,对 S 值的测试和做 S=S-1 操作时都是不可中断的。

2. 记录型信号量

整型信号量的问题:忙等,即当 wait(S) 中信号量 S<=0 时,会不停地进行测试,因此未遵循让权等待的原则。而记录型信号量机制则是一种不存在 “忙等” 现象的进程同步机制。

记录型信号量的数据结构可描述如下:

typedef struct {int value;struct process_control_block * list;
} semaphore;

原子操作 wait(S) 和 signal(S) 可描述如下:

wait(semaphore * S) {S->value--;if(S->value < 0) block(S->list);//S->value == 0时代表刚好取走最后一个资源
}signal(semaphore * S) {S->value++;if(S->value <= 0) wakeup(S->list);//S->value == 0时代表刚好还有一个进程被阻塞
}

整型信号量和记录型信号量的问题:

  • 只能有效地解决多个进程共享一种临界资源的情况
  • 即只需要设置一个临界区

下面来看多个进程需要访问多种临界资源的情况。假设进程 A 和 B 需要访问共享数据 D 和 E,设置互斥型信号量 Dmutex 和 Emutex,两者初始值均为 1,进程 A 和 B 的访问操作如下:

process A:         |process B:
wait(Dmutex);      |wait(Emutex);
wait(Emutex);      |wait(Dmutex);
signal(Emutex);    |signal(Dmutex);
signal(Dmutex);    |signal(Emutex);

若进程 A 和 B 按下述次序交替执行 wait 操作:

process A: wait(Dmutex);    //Dmutex=0
process B: wait(Emutex);    //Emutex=0
process A: wait(Emutex);    //Emutex=-1, A blocked
process B: wait(Dmutex);    //Dmutex=-1, B blocked

进程阻塞以后也不能释放已持有的资源。最后,进程 A 和 B 就将处于僵持状态。在无外力作用下,两者都将无法从僵持状态中解脱出来。我们称此时的进程 A 和 B 已进入死锁状态。

3. AND 型信号量

AND 同步机制的基本思想:将进程在整个运行过程中需要的所有资源,一次性全都地分配给进程,待进程使用完后再一起释放。只要尚有一个资源未能分配给进程,其它所有可能为之分配的资源也不分配给它。

对若干个临界资源的分配采取原子操作:要么把它所请求的资源全部分配到进程,要么一个也不分配。具体方法是在 wait 操作中,增加了一个 “AND” 条件,故称为 AND 同步,或称为同时 wait 操作(simultaneous wait)。

Swait 操作定义如下:

Swait(S1, S2, ... , Sn) {while(true) {if(S1 >= 1 && S2 >= 1 && ... && Sn >= 1) {for(i = 1; i <= n; ++i) Si = Si - 1;break;  //分配完资源后,直接退出while循环} else {/*place the process in the waiting queue associated withthe first Si found with Si<1, and set the program countof this process to the beginning of Swait operation*/}}
}

Ssignal 操作定义如下:

Ssignal(S1, S2, ... , Sn) {for(i = 1; i <= n; ++i) Si = Si + 1;/*remove all the process waiting in the queueassociated with Si into the ready queue*/
}

4. 信号量集

在每次分配时,采用信号量集来控制,可以分配多个资源。

Swait 操作定义如下:

Swait(S1, t1, d1, ... , Sn, tn, dn) {while(true) {if(S1 >= t1 && ... && Sn >= t1) {for(i = 1; i <= n; ++i) Si = Si - di;break;  //分配完资源后,直接退出while循环} else {/*place the process in the waiting queue associated withthe first Si found with Si

Ssignal 操作定义如下:

Ssignal(S1, d1, ... , Sn, dn) {for(i = 1; i <= n; ++i) Si = Si + di;/*remove all the process waiting in the queueassociated with Si into the ready queue*/
}

三种特例

1)Swait(S, d, d):只有一种信号量 S,允许进程每次申请 d 个资源,当现有资源少于 d 时,不予分配。

2)Swait(S, 1, 1):只有一种信号量 S,允许进程每次申请 1 个资源,当现有资源少于 1 时,不予分配。当 S = 1 时,代表资源总量为 1,从而信号量集退化为互斥信号量;当 S > 1 时,代表资源总量大于 1,从而信号量集退化为记录型信号量。

3)Swait(S, 1, 0):可控开关。当 S >= 1 时,允许多个进程进入某特定区;当 S = 0 时,将阻止任何进程进入特定区。

读写文件举例:允许多个读进程进入临界区,但一旦有一个写进程进入临界区,则将阻止任何进程进入临界区。

P0:Swait(S, 1, 0)  //S>=1成立,且不改变信号量
P1:Swait(S, 1, 0)  //S>=1成立,且不改变信号量
Pw:Swait(S, 1, 1)  //S>=1成立,且S-1=0
P2:Swait(S, 1, 0)  //S>=1不成立

2.4.4 信号量的应用

1. 利用信号量实现进程互斥

为使多个进程能互斥地访问某临界资源,只须为该资源设置一互斥信号量 mutex,并设其初始值为 1,然后将各进程访问该资源的临界区 CS 置于 wait(mutex) 和 signal(mutex) 操作之间即可。

  1. 设置一互斥信号量 mutex
  2. 设其初始值为 1
  3. 将临界区 CS 置于 wait(mutex) 和 signal(mutex) 之间

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

  • mutex 互斥
  • semaphore 信号量
  • 老师用 Pascal 写的,我不能保证我语法正确
var mutex:semaphore:=1; //将mutex定义为semaphore类型,且赋初值为1
begin
parbeginprocess1: beginrepeatwait(mutex);//critical sectionsignal(mutex);//remainder sectionuntil falseendprocess2: beginrepeatwait(mutex);//critical sectionsignal(mutex);//remainder sectionuntil falseendparend
end

注意:

  • 对于互斥型信号量,wait(mutex) 和 signal(mutex) 必须成对出现;
  • 缺少 wait(mutex) 导致系统混乱,不能保证对临界资源的互斥访问;
  • 缺少 signal(mutex) 会使临界资源永远不被释放,等待该资源的进程不能被唤醒。

2. 利用信号量实现前趋关系

利用信号量来描述程序或语句之间的前趋关系。

其中,Si 是需要执行的语句。

p1(){ S1; signal(a); signal(b); }
p2(){ wait(a); S2; signal(c); signal(d); }
p3(){ wait(b); S3; signal(e); }
p4(){ wait(c); S4; signal(f); }
p5(){ wait(d); S5; signal(g); }
p6(){ wait(e); wait(f); wait(g); S6; }void main() {semaphore a, b, c, d, e, f, g;//将信号量初值均设置为0,若后续进程试图执行则必被阻塞a.value = b.value = c.value = 0;d.value = e.value = f.value = g.value = 0;cobegin  //采用并行执行p1(); p2(); p3(); p4(); p5(); p6();coend;
}

2.4.5 管程机制

当共享资源用共享数据结构表示时,资源管理程序可用对该数据结构进行操作的一组过程来表示(例如,资源的请求过程 request 和释放过程 release),我们把这样一组相关的数据结构和过程一并称为管程(monitors)。
Hansan 为管程所下的定义是:“一个管程定义了一个数据结构和能为并发进程所执行(在该数据结构上)的一组操作,这组操作能同步进程和改变管程中的数据”。

1. 管程的组成

  • 管程的名字
  • 局部于管程的共享变量说明
  • 对该数据结构进行操作的一组过程
  • 对局部于管程的数据设置初始值的语句

Monitor(管程)—— 面向对象方法  

2. 管程的主要特点

局部数据变量只能被管程的过程访问,任何外部过程都不能访问。

一个进程通过调用管程的一个过程进入管程。

在任何时候,只能有一个进程在管程中执行,调用管程的任何其他进程都被挂起,以等待管程变成可用的。

相关内容

热门资讯

安卓系统苹果手机识别,跨界融合... 你知道吗?在科技飞速发展的今天,手机已经成为了我们生活中不可或缺的一部分。而说到手机,安卓系统和苹果...
harmonyos系统是不是安... 亲爱的读者,你是否曾好奇过HarmonyOS系统与安卓系统之间的关系?是不是安卓的“亲戚”?今天,就...
手机怎么装系统安卓,安卓系统安... 手机卡顿了?想给安卓系统来个大变身?别急,跟着我一步步来,保证让你的手机焕然一新!一、准备工作在开始...
安卓Linux系统内网穿透,A... 你有没有想过,你的安卓手机里那些看似普通的APP,其实可能正在悄悄地帮你打通网络世界的任督二脉呢?没...
win怎么安装安卓系统,Win... 亲爱的读者,你是不是对Win系统上的安卓应用垂涎已久,但又苦于不知道如何安装安卓系统呢?别急,今天我...
升级小米平板安卓系统,畅享全新... 你有没有发现,你的小米平板用久了,是不是感觉有点卡呢?别急,今天就来教你怎么给它来个系统升级,让它焕...
捷豹安卓系统车载,捷豹安卓系统... 哇,你有没有想过,当你的手机和汽车融为一体,会是怎样的体验呢?想象你正驾驶着你的捷豹,车窗外的风景如...
安卓1到10系统,安卓1.0至... 你有没有想过,手机里的安卓系统就像是我们生活中的好朋友,从青涩的少年成长为稳重的青年呢?从安卓1.0...
安卓8.0停用系统应用,提升使... 你知道吗?最近安卓系统又来了一次大动作,那就是安卓8.0系统开始停用一些系统应用了。这可真是让人有点...
安卓系统修改mtu值,轻松提升... 你有没有想过,你的安卓手机其实是个小小的电脑呢?它里面藏着许多可以自定义的秘密功能,就像修改MTU值...
安卓平板改window系统,探... 你有没有想过,你的安卓平板其实可以摇身一变,变成一个Windows系统的电脑呢?没错,就是那种可以运...
时空猎人安卓苹果系统,探索无尽... 你知道吗?最近在手机游戏圈里,有一款叫做《时空猎人》的游戏可是火得一塌糊涂呢!不管是安卓用户还是苹果...
安卓9.0系统的电视,新一代电... 亲爱的读者们,你是否也像我一样,对科技新玩意儿充满好奇?今天,我要和你聊聊一个让人眼前一亮的话题——...
小pc安装安卓系统,轻松安装安... 你有没有想过,你的小PC也能变身成为安卓系统的超级玩家呢?没错,就是那个平时默默无闻的小家伙,现在也...
高通备份安卓系统,全方位数据安... 你知道吗?在这个科技飞速发展的时代,手机备份可是个不得不提的话题。尤其是对于安卓用户来说,选择一个靠...
谷歌安卓系统有多少,从诞生到全... 你有没有想过,那个无处不在的谷歌安卓系统,究竟在全球有多少用户呢?它就像一个神秘的数字,每天都在悄悄...
fc黄金传说安卓系统,畅享复古... 你有没有听说最近安卓系统上的一款超酷的游戏——《FC黄金传说》?这款游戏可是让不少玩家都沉迷其中,今...
变小的我安卓系统,安卓系统演变... 你有没有发现,最近你的手机好像变轻了?没错,说的就是你,那个陪伴你多年的安卓系统。它悄无声息地进行了...
vivo安卓系统小彩蛋,体验科... 你知道吗?在vivo的安卓系统中,竟然隐藏着一些超有趣的小彩蛋!这些小彩蛋就像是在手机里埋下的宝藏,...
安卓系统如何强制重启,安卓系统... 手机突然卡壳了,是不是又该给它来个“大保健”了?没错,今天就来聊聊安卓系统如何强制重启。别小看这个看...