信号量机制

1.整型信号量

整型信号量定义为一个用于表示资源数目的整型量,除了初始化外,只能由wait(S)和signal(S)这两个操作访问。wait又称为P操作,signal又称为V操作。

wait(S){while(S<=0);   /*do no-op*/S--;
}
signal(S){S++;
}

在wait操作中,当S<=0,表示资源数目不够,这时就会一直在while循环中,并什么都不做,使得进程处于“忙等”状态。

wait和signal可以理解为对资源数目的-1和+1,一次wait操作表明要使用一个资源,一次signal操作表明归还一个资源或者产生一个资源。

2.记录型信号量

记录型信号量可以解决上述的“忙等”问题,不会一直停留在wait操作中,但是会出现多个进程等待访问同一临界资源的情况。为此除了表示资源数目的整型变量为value,还增加了一个进程链表指针list,用于链接上述的所有等待进程。

记录型数据结构

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

wait和signal操作

wait(semaphore *S){S->value--;if(S->value<0) block(S->list);
}
signal(semaphore *S){S->value++;if(S->value<=0) wakeup(S->list);
}

在wait操作中,先自减,如果资源数目小于0,说明资源不够用,这时就要把该进程从运行状态block为阻塞状态 ,进程需要等待,但是该进程还是获取了需要的资源。此时S->value的绝对值表示在该信号量链表中已阻塞进程的数目。

在signal操作中,先自增即释放资源,如果资源数目小于等于0,则需要唤醒链表中的进程,把它从阻塞状态改变为就绪状态。

当S->value=1,表示只允许一个进程访问临界资源此时信号量转变为互斥信号量,用于进程互斥。

3.AND型信号量

前面两个信号量只能解决多个进程对应一种资源的情况,当多个进程需要多种资源,就需要用到AND型信号量。

死锁问题:

假设两个进程A和B,都需要访问互斥型信号量Dmutex=1和Emutex=1。

process A:          process B:

step1: wait(Dmutex);     wait(Emutex);

step2: wait(Emutex);     wait(Dmutex);

当A和B都进行完step1操作时,Dmutex=0,Emutex=0.进行step2操作时,Emutex=-1,Dmutex=-1,则A和B都被阻塞。

这时A和B就进入死锁状态。

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

Swait(S1,S2,....Sn){while(TRUE){if(S1>=1&&S2>=1&&.....Sn>=1){for(i=1;i<=n;i++)Si--;break;}else{由于有资源未能分配给进程,其他所有资源都不分配给它}}
}
Ssignal(S1,S2,....Sn){while(TRUE){for(i=1;i<=n;i++){Si++;}}
}

4.信号量集

在上述操作中,wait和signal都只能对信号量+1和-1,也就一位置不能对临界资源进行多个单位的申请和释放。当需要N个单位的资源时,要进行N个wait操作,很低效,此外当所申请的资源数量低于某一个下限值,不予以分配,从而保证系统的安全性。

设该资源的分配下限值为ti,即最大申请值不能超过ti,对该资源申请量为di。当Si<ti,就不给分配,一旦允许分配,Si=Si-di。

Swait(S1,t1,d1,....Sn,tn,dn)

Ssignal(S1,d1,....Sn,dn)

特殊情况:

1.Swait(S,d,d)。此时在信号量集中只有一个信号量S,但允许它每次申请d个资源,当现有资源少于d时,不予分配。

2.Swait(S,1,1)。此时信号量集已经蜕化为一般的记录型信号量(S>1时)或互斥信号量(S=1时)。

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

信号量的应用

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

两个进程的互斥

设互斥信号量mutex=1,初值为1,取值范围为(-1,0,1)。当mutex=1时,表示两个进程皆未进入需要互斥的临界区;当mutex=0时,表示有一个进程进入临界区运行,另外一个必须等待,挂入阻塞队列;当mutex=-1,时,表示有一个进程正在临界区运行,另外一个进程因等待而阻塞在信号量队列中,需要被当前已经在临界区运行的进程退出时唤醒。

mutex=0和mutex=-1时都需要阻塞,但是mutex=-1时阻塞的进程需要被唤醒,即wakeup操作。

semaphore mutex=1;PA(){while(1){wait(mutex);临界区;signal(mutex);剩余区;}}PB(){while(1){wait(mutex);临界区;signal(mutex);剩余区;}}

在利用信号量机制实现进程互斥时应该注意,wait(mutex)和signal(mutex)必须成对地出现。缺少wait(mutex)将会导致系统混乱,不能保证对临界资源的互斥访问;而缺少signa(mutex)将会使临界资源永远不被释放,从而使因等待该资源而阻塞的进程小能被突。

补充:

一个访问临界资源的循环进程描述如下:

while(TRUE){进入区临界区退出区剩余区
}

在每个进程中访问临界资源的那段代码称为临界区(riticalsection)。显然,若能保证诸进程互斥地进入自己的临界区,便可实现诸进程对临界资源的互斥访问。为此,每个进程在进入临界区之前,应先对欲访问的临界资源进行检查,看它是否正被访问。如果此刻临界资源未被访问,进程便可进入临界区对该资源进行访问,并设置它正被访问的标志;如果此刻该临界资源正被某进程访问,则本进程不能进 入临界区。因此,必须在临界区前面增加一段用 于进行上述检查的代码,把这段代码称为进入区(enry section)。 相应地,在临界区后面也要加上一段称为退 出区(exit sction)的代码,用于将临界区正被访问的标志恢复为末被访间的标志。进程中除上述进入区、临界区及退出区之外的其它部分的代码在这里都称为剩余区。

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

var  a1,a2,a3,a4,a5,a6,a7:semaphore: =0;beginparbegins1:begin  s1;  V(a1)  ;  V(a2)  ;  ends2:begin  P(a1)  ;  s2  ;  V(a4)  ;  V(a5)  ;  ends3:begin  P(a1)  ;  s3  ;  V(a6)  ;  ends4:begin  P(a2)  ;  s4  ;  V(a6)  ;  ends5:begin  P(a2)  ;  s5  ;  V(a6)  ;  ends6:begin  P(a3)  ;  P(a4)  ;  P(a5)  ;   s6  ;  end

看看就懂,不过多解释。

典型例题

1.生产者——消费者问题

该问题描述了两个共享固定大小缓冲区的线程——即所谓的“生产者”和“消费者”——在实际运行时会发生的问题。生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程。与此同时,消费者也在缓冲区消耗这些数据。该问题的关键就是要保证生产者不会在缓冲区满时加入数据,消费者也不会在缓冲区中空时消耗数据。

1.利用记录型信号量解决生产者消费者问题

假定在生产者和消费者之间的公用缓冲池中具有n个缓冲区,这时可利用互斥信号量mutex实现诸进程对缓冲池的互斥使用;利用信号量empty和full分别表示缓冲池中空缓冲区和满缓冲区的数量。又假定这些生产者和消费者相互等效,只要缓冲池未满,生产者便可将消息送入缓冲池;只要缓冲池未空,消费者便可从缓冲池中取走一个消息。对生产者-消费者问题可描述如下:

int in=0, out=0;item buffer[n];semaphore mutex =l, empty=n, full=0;
void proceducer() {do {producer an item nextp;......wait(empty);//申请一个空的缓冲区wait(mutex);//申请互斥信号量,不准其他进程进入buffer[in] =nextp;//产品送入in=(in+1) % n;//下一个生产者 signal(mutex);//释放互斥信号量.准许其他进程进入signal(full);//释放一个满的缓冲区}while(TRUE);
}void consumer(){do {wait(full);//申请一个满的缓冲区wait(mutex);//申请互斥信号量,不准其他进程进入nextc= buffer[out];//产品拿出out =(out+l) % n;//下一个消费者signal(mutex);//释放互斥信号量.准许其他进程进入signal(empty);//释放一个空的缓冲区consumer the item in nextc;...}while(TRUE);
}void main {cobeginproducer();consumer();coend
}

用于实现互斥的信号量必须成对出现。

对于empty和full的wait和signal操作,也需要成对出现,但它们分别处于不同的进程中。

2.利用AND信号量解决生产者——消费者问题

int in= 0, out= 0;item buffer[n];semaphore mutex = 1, empty = n, full= 0;
void producer{do{producer an item nextp;Swait(empty, mutex);buffer[in] = nextp;in=(in+1) % n;Ssignal(mutex, full);}while(TRUE);void consumer(){do {Swait(full, mutex);nextc = buffer[out];out= (out+1)% n;Ssignal(mutex, empty);consumer the item in nextc;}while(TRUE);
}

只是把两个wait变为一个Swait,两个signal变为一个Ssignal 。

2.哲学家进餐问题

有五个哲学家,他们的生活方式是交替地进行思考和进餐,哲学家们共用一张圆桌,分别坐在周围的五张椅子上,在圆桌上有五个碗和五支筷子,平时哲学家进行思考,饥饿时便试图取其左、右最靠近他的筷子,只有在他拿到两支筷子时才能进餐,该哲学家进餐完毕后,放下左右两只筷子又继续思考。

1.利用记录型信号量解决哲学家进餐问题

经分析可知,放在桌子上的筷子是临界资源,在一段时间内只允许一位哲学家使用。为了实现对筷子的互斥使用,可以使用一个信号量表示一只筷子,由这五个信号量构成信号量数组。其描述如下:

semaphore chopstick[5]={1,1,1,1,1}

所有信号量均被初始化为1,第i位哲学家的活动可以描述为:

do{wait(chopstick[i]);//拿左边筷子wait(chopstick[(i+1)%5)]);//拿右边筷子...//eat...signal(chopstick[i]);//放下左边筷子signal(chopstick[(i+1)%5]);//放下右边筷子...//think...}while(TRUE)

假如五位哲学家同时拿起左边的筷子时,就会使五个信号量chopstick 均为0:当他们再试图去拿右边边的筷子时,都将因无筷子可拿而无限期地等待。对于这样的死锁问题,可采取以下几种解决方法:
(1)至多只允许有四位哲学家同时去拿左边的筷子,最终能保证至少有一位哲学家能够进餐,并在用毕时能释放出他用过的两只筷子,从而使更多的哲学家能够进餐。
(2)仅当哲学家的左、右两只筷子均可用时,才允许他拿起筷子进餐。
(3)规定奇数号哲学家先拿他左边的筷子,然后再去拿右边的筷子:而偶数号哲学家则相反。按此规定,将是1、2号哲学家竞争1号筷子: 3、4号哲学家竞争3号筷子。即五位哲学家都先竞争奇数号筷子,获得后,再去竞争偶数号筷子,最后总会有一位哲学家能获得两只筷子而进餐。

semaphore chopstick[5]=(1, 1,1,1, 1);void philosopher(int i)while(true){if(¡ mod2 =0){//偶数哲学家,先右后左。wait (chopstick [(¡ + 1) mod 5]);wait (chopstick [ï]);eat();signal (chopstick [i);signal (chopstick[(i+ 1) mod 5]);
}else{//奇数哲学家,先左后右。wait (chopstick [i]);wait (chopstick [(i+ 1) mod 5]);eat;signal (chopstick [(i+1) mod 5]);signal (chopstick [i]);}
}

2.利用AND信号量机制解决哲学家就餐问题

利用AND信号量机制可以解决上述死锁

semaphore chopstick[5]= [1,1,1,1,1];do{//thinkSwait(chopstick[(i+ 1)%5], chopstick[i]);//eatSsignal(chopstick[(i+1)%5], chopstick[i]);}while[TRUE];

3.读者——写者问题

1.允许多个读者可以同时对文件执行读操作
2.只允许一个写者往文件写信息
3.任一写者在完成写操作之前不允许其他读者后写者工作
4.写者执行写操作前,应该让已有的读者或者写者全部退出

等我有时间补充

信号量机制以及各种例题相关推荐

  1. GCD之信号量机制二

    在前面GCD之信号量机制一中介绍了通过信号量设置并行最大线程数,依此信号量还可以防止多线程访问公有变量时数据有误,下面的代码能说明. 1.下面是不采用信号量修改公有变量的值 dispatch_grou ...

  2. 十六、用信号量机制实现进程互斥、同步、前驱关系

    一.知识总览 二.信号量机制实现进程互斥 注意: 1.信号量mutex表示进入临界区的名额 2.对不同的临界资源需要设置不同的互斥信号量 3.P.V操作必须成对出现,缺少P(mutex)就不能保证临界 ...

  3. 卡住无法查看到所有进程_进程同步 进程互斥 软件和硬件实现方式 信号量机制 信号量机制实现进程同步,进程互斥,前驱关系...

    参考:https://www.bilibili.com/video/av31584226/?p=9 进程具有异步性的特征,异步性是指,各并发执行的进程以各自独立的,不可预知的速度向前推进. 回忆我们之 ...

  4. 操作系统(三)| 进程同步详解(主要任务、制约关系、临界资源、临界区、同步机制遵循规则、信号量机制、信号量的应用)

    文章目录 进程的同步基本概念 进程同步的主要任务 进程间的制约关系 临界资源 临界区 同步机制应遵循的规则 信号量机制 整型信号量 记录型信号量 ❤❤❤ AND型信号量 信号量的应用 实现进程互斥 实 ...

  5. 操作系统(二十二)用信号量机制实现进程互斥、同步、前驱关系

    2.3.5 用信号量机制实现进程互斥.同步.前驱关系 目录 2.3.5 用信号量机制实现进程互斥.同步.前驱关系 2.3.5.1 用信号量机制实现进程互斥 2.3.5.2 用信号量机制实现进程同步 2 ...

  6. 操作系统(二十一)信号量机制

    2.3.4 信号量机制 在前两节中我们分别学习了用软件方式以及硬件方式实现互斥访问,但是他们或多或少的存在一些问题,1965年荷兰的一名学者迪杰斯特拉(是的,就是那个男人)提出了信号量机制,有效的解决 ...

  7. 2.3.5 操作系统之信号量机制实现进程的互斥、同步与前驱关系

    文章目录 0.思维导图 1.信号量机制实现进程互斥 2.信号量机制实现进程同步 3.信号量机制实现前驱关系 0.思维导图 在看此小结内容之前,需熟悉这一篇博客里面的知识,关于P.V操作内部实现原理等h ...

  8. 2.3.4 操作系统之信号量机制(整型信号量、记录型信号量P、V)

    文章目录 0.思维导图 1.为什么引入信号量机制? 2.什么是信号量机制? 3.整型信号量 4.记录型信号量 (1)举一个生动形象的例子了解记录型信号量 (2)梳理一下记录型信号量的知识点(P.V) ...

  9. 操作系统 第二章【记录型信号量机制、独木桥问题】【MOOC答案】

    目录 第1题 第2题 第3题 第4题 第1题 1( 30分 ) 简述生产者消费者问题的解决方案,并说明用记录型信号量机制解决生产者消费者问题时Wait()操作的次序不当会在什么情况下引发死锁. 得分指 ...

最新文章

  1. 程序员的快速开发框架:Github上 10 大优秀的开源后台控制面板
  2. Linux 内核详解以及内核缓冲区技术
  3. 三、神兽变变变(下)
  4. 【Python】csv、excel、pkl、txt、dict
  5. android6.0源码分析之Zygote进程分析
  6. dw怎么在框架中加入网页_怎样使用iframe,在网页中插入页面
  7. 盖茨依然坐镇微软搜索团队 要与谷歌争高下
  8. paper 6:支持向量机系列三:Kernel —— 介绍核方法,并由此将支持向量机推广到非线性的情况。...
  9. 杨辉三角形(C语言)(使用一维数组的版本)
  10. 阿里巴巴的26款超神Java开源项目!建议收藏~
  11. saltstack高效运维
  12. php主机卫士,Bypass360主机卫士SQL注入防御八种姿势
  13. php实现tptp客户端
  14. WIDS(无线入侵检测)
  15. 支付宝支付(沙箱环境)
  16. 正定子龙大桥正式开工建设
  17. HTML+CSS实现(排行榜+棋盘+表格+图片商品列表)
  18. 贸然用string比较的后果
  19. DHCP动态分配ip地址
  20. 新型多功能6轴小型机器人

热门文章

  1. 华为荣耀10长按Android版本,华为荣耀10是什么系统
  2. SD存储卡读写速度比较
  3. 优化设计-有约束复合型法-MATLAB编程求解
  4. Python + AI人工智能——给老照片恢复色彩、上色
  5. k8s: the connection to the server 192.168.2.94:6443 was refused 解决方法
  6. 雪花算法snowflake分布式id生成原理详解,以及对解决时钟回拨问题几种方案讨论
  7. 如何通过微信电脑客户端,快速加微信群内的好友
  8. 中国商业航天产业深度研究与投资方向预测报告2022-2028年版
  9. emWin 模拟器的使用(VS2017+Win10)
  10. 重复性管理——抽象的重要性(下)