5.2 信号量机制

信号量机构是一种功能较强的机制,可用来解决互斥与同步的问题。在长期且广泛的应用中,信号量机制得到了很大的发展。由最初的整形信号量,经过记录性信号量、AND信号量,最后发展为“信号量集”。

一、信号量的分类

1.整型信号量

整型信号量被定义为一个用于表示资源数目的整型量S,它只能被两个标准的原语wait(S)和signal(S)来访问,也可以记为“P操作”和“V操作”。可描述为:

 wait(S){
     while (S<=0);
     S=S-1;
 }//p操作
 signal(S){
     S=S+1;
 }//v操作

wait操作中,只要信号量S<=0,就会不断地测试。因此,该机制并未遵循“让权等待” 的准则,而是使进程处于“忙等”的状态。

2.记录型信号量

记录型信号量是不存在“忙等”现象的进程同步机制。除了需要一个用于代表资源数目的整型变量value外,再增加一个进程链表L,用于链接所有等待该资源的进程,记录型信号量是由于釆用了记录型的数据结构得名。记录型信号量可描述为:

 typedef struct{
     int value;
     struct process *L;
 } semaphore;

相应的wait(S)和signal(S)的操作如下:

 void wait (semaphore S) { //相当于申请资源
     S.value--;
     if(S.value<0) {
         add this process to S.L;
         block(S.L);
     }
 }

wait操作,S.value--,表示进程请求一个该类资源,当S.value<0时,表示该类资源已分配完毕,因此进程应调用block原语,进行自我阻塞,放弃处理机,并插入到该类资源的等待队列S.L中,可见该机制遵循了“让权等待”的准则。

 void signal (semaphore S) { //相当于释放资源
     S.value++;
     if(S.value<=0){
         remove a process P from S.L;
         wakeup(P);
     }
 }

signal操作,表示进程释放一个资源,使系统中可供分配的该类资源数增1,故S.value++。若加1后仍是S.value<=0,则表示在S.L中仍有等待该资源的进程被阻塞,故还应调用wakeup 原语,将S.L中的第一个等待进程唤醒。

3.AND信号量

上述进程互斥问题都是针对一个临界资源而言的,在有些应用场合,一个进程需要同时获得两个或者更多的资源。AND信号量可以解决多临界资源申请问题。假设有S1,...Sn,N个资源,进程必须申请到所有资源后才可执行,则其wait 和signal描述为:

 void wait(S1, S2, ... , Sn){
     if (S1>=1 && S2>=1 && ... && Sn>=1 )
         for (int i=1; i<n; i++)
             Si = Si - 1;
     else 
         place this process//将当前进程放置在第一个不满足Si>=1的阻塞队列中      
 }
 void signal(S1, S2, ... , Sn){
     for (int i=1; i<n; i++)
         Si = Si + 1;
     romove all the process waiting in the queue associated with Si into ready queue
 }

4.信号量集

在记录型信号量机制中,wait和signal操作只能进行加一减一的操作。当需要一次性需要申请N个同类资源时,需要进行N次操作,这显然是低效的。为方便对资源的控制,每种资源在分配前需要检查其数量是否在其极限值之上。为此,对AND信号量进行扩充。S为信号量,d为需求量,t为下限值:

 void wait(S1, d1, t1, S2, d2, t2, ... , Sn, dn, tn){
     if (S1>=t1 && S2>=t2 && ... && Sn>=tn )
         for (int i=1; i<n; i++)
             Si = Si - dn;
     else 
         place this process//将当前进程放置在第一个不满足Si>=1的阻塞队列中      
 }
 void signal(S1, d1, S2, d2, ... , Sn, dn,){
     for (int i=1; i<n; i++)
         Si = Si + dn;
     romove all the process waiting in the queue associated with Si into ready queue
 }

二、信号量的应用

1.利用信号量实现同步

信号量机构能用于解决进程间各种同步问题。设S为实现进程P1、P2同步的公共信号量,初值为0。进程P2中的语句y要使用进程P1中语句x的运行结果,所以只有当语句x执行完成之后语句y才可以执行。其实现进程同步的算法如下:

 semaphore S = 0; //初始化信号量
 P1 ( ) {
     P1 process
     x; //语句x
     V(S); //告诉进程P2,语句乂已经完成
 }
 P2()){
     P2 process1
     P(S) ; //检查语句x是否运行完成
     y; // 检查无误,运行y语句
     P2 process2
 }

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

信号量机构也能很方便地解决进程互斥问题。设S为实现进程Pl、P2互斥的信号量,由于每次只允许一个进程进入临界区,所以S的初值应为1(即可用资源数为1)。只需把临界区置于P(S)和V(S)之间,即可实现两进程对临界资源的互斥访问。其算法如下:

 semaphore S = 1; //初化信号量
 P1 ( ) {
     P1 process1
     P(S); // 准备开始访问临界资源,加锁
     // 进程P1的临界区
     V(S); // 访问结束,解锁
     P1 process2
 }
 P2() {
     P2 process1
     P(S); //准备开始访问临界资源,加锁
     // 进程P2的临界区;
     V(S); // 访问结束,解锁
     P2 process2
 }

3.利用信号量实现前驱关系

信号量也可以用来描述程序之间或者语句之间的前驱关系。下图给出了一个前驱图,其中S1, S2, S3, …, S6是最简单的程序段。为保证S1 -> S2、 S1 -> S3、 S2 -> S4、S2 ->S5、S3 -> S6、S4 -> S6、S5 -> S6等前驱关系需要设置信号量a1、a2、bl、b2、c、d、e,并初始化为0。



实现算法如下:

semaphore al=a2=bl=b2=c=d=e=0; //初始化信号量
 S1() {
     S1 process
     V(al); V(a2) ; //S1已经运行完成
 }
 S2() {
     P(a1); //检查S1是否运行完成
     S2 process
     V(bl); V(b2); // S2已经运行完成
 }
 S3() {
     P(a2); //检查S1是否已经运行完成
     S3 process
     V(c); //S3已经运行完成
 }
 S4() {
     P(b1); //检查S2是否已经运行完成
     S4 process
     V(d); //S4已经运行完成
 }
 S5() {
     P(b2); //检查S2是否已经运行完成
     S5 process
     V(e); // S5已经运行完成
 }
 S6() {
     P(c); //检查S3是否已经运行完成
     P(d); //检查S4是否已经运行完成
     P(e); //检查S5是否已经运行完成
     S6 process
 }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,639评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,277评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,221评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,474评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,570评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,816评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,957评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,718评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,176评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,511评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,646评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,322评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,934评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,755评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,987评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,358评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,514评论 2 348

推荐阅读更多精彩内容

  • ** 本文摘自汤小丹主编《计算机操作系统》(第三版)2.3 进程同步 ** 在 OS 中引入进程后,虽然提高了资源...
    刘帅_阅读 3,091评论 0 0
  • 一、 【例3-1-4】在操作系统中,要对并发进程进行同步的原因是 。 A. 进程必须在有限的时间内完成 B. 进程...
    ZoeyeoZ阅读 4,948评论 0 9
  • 又来到了一个老生常谈的问题,应用层软件开发的程序员要不要了解和深入学习操作系统呢? 今天就这个问题开始,来谈谈操...
    tangsl阅读 4,098评论 0 23
  • 他向她挥了挥手,看着她走进了地车站,便转身回去了。 在路上,他走着,想着这两天发生的事,如梦一般。他为自己的表现颇...
    墨客沐阳阅读 464评论 1 6
  • 罗小姐在很小的时候就是一个爱哭的孩子,走路摔倒哭,下雨打雷哭,玩具被抢哭,看不见奶奶也会哭。我们一帮孩子...
    夜小胖阅读 377评论 0 0