信号量答案

发布 2022-09-03 00:17:28 阅读 1537

第一部分。

该方法对可抢占调度完全没问题。事实上,它就是为这种情况设计的。当调度为不可抢占的,该方法将会失败。假设turn初值为0,而进程1首先运行。它将一直循环,永不释放cpu。

对于内核线程,线程可以在信号量上阻塞,而内核可以运行该进程中的其它线程。因而,使用信号量没有问题。而对于用户级线程,当某个线程在信号量上阻塞时,内核将认为整个进程都被阻塞,而且不再执行它。

因此,进程失败。

4、某商店有两种食品a和b, 最大数量各为m个。该商店将a、b两种食品搭配**,每次各取一个。为避免食品变质,遵循先到食品先**的原则。

有两个食品公司分别不断地**a、b两种食品(每次一个)。为保证正常销售,当某种食品的数量比另一种的数量超过k(k小于m)个时,暂停对数量大的食品进货。试用p、v操作解决上述问题中的同步和互斥关系。

4、参***。

#define max m /*最大数量*/

typedef int semaphore;

*初始化*/

semaphore a_full = 0; /商店中a食品数目假设初始值为0*/

semaphore b_full = 0; /商店中b食品数目假设初始值为0*/

semaphore a_empty = max; /a可缓冲数目 */

semaphore b_empty = max; /b 可缓冲数目 */

semaphore a_minus_b = k; /商店中 a超过 b的数目初始值为 k-(a_full – b_full) *

semaphore b_minus_a = k;/*商店中 b超过 a 的数目初始值为 k- (b_full – a_full) *

queue q_a,q_b; /先进先出的队列模拟商店中两食品资源*/

semaphore qa_mutex = 1; /队列a互斥量*/

semaphore qb_mutex = 1; /队列b互斥量*/

* 商店搭配** a b进程*/

void shop_a_b ()商店**a b进程两食品搭配***/

a a;b b;

while(1)

p(a_full);

p(b_ful);

p(qa_mutex);

a = q_ /从商店中取出a*/

v(qa_mutext);

p(qb_mutex)

b = q_从商店中取出b*/

v(qb_mutex);

v(a_empty);

v(b_empty);

sell(a,b); 卖出 a,b*/

*总结:相当于生产者消费者问题中的消费者,首先执行将a,b中的空槽减一,然后开始临界区操作,此处分别有两种商品,因此分别有qa-mutex和qb_mutex两个互斥量。同时,为满足题目中先到先出的要求,采用队列的方式取出商品。

完成临界区操作后,执行v(a_empty)和v(b_empty)操作。*/

*食品公司向商店提供a 进程*/

void stock_a() 进货a*/

a a;while(1)

a = geta();

p(a_empty);

p(a_minus_b); the key of this problem

p(qa_mutex);

q_v(qa_mutex);

v(a_full);

v(b_minus_a);

*总结:相当于生产者消费者问题中的生产者,每次先生产一个产品,首先将空槽的数量减少一个,由于a产品数量增加了一个,所以a减b的量的允许值也少了一个(与k比较)。然后开始临界区操作,使用qa_mutex来对a产品有关的临界区访问进行互斥。

最后将满槽的数目加一,由于b相对于a减一,故允许的b减a的差值加一*/

*食品公司向商店提供b 进程*/

void stock_b() 进货b*/

b b;while(1)

b = getb();

p(b_empty);

p(b_minus_a);

p(qb_mutex);

q_v(qb_mutex);

v(b_full);

v(a_minus_b);

第4题总结:(1)主要是模仿生产者消费者问题,相当于两个生产者一个消费者的问题。

2)涉及到了两个不同商品的临界区访问,主要是确定临界区操作所涉及的具体对象。同时,当涉及先进先出问题时,优先考虑队列操作。

5、考虑具有如下特征的共享资源:(1)当使用该资源的进程小于3个时,新申请资源的进程可以立刻获得资源;(2)当三个资源都被占用后,只有当前使用资源的三个进程都释放资源后,其他申请资源的进程才能够获得资源。由于需要使用计数器来记录有多少进程正在使用资源和等待资源,而这些计数器自身也需要互斥执行修改动作的共享资源,所以可以采用如下的程序:

1 semaphore mutex = 1, block = 0;

2 int active = 0, waiting = 0;

3 boolean must_wait = false;

5 semwait(mutex);

6 if(must_wait)

13 ++active;

14 must_wait = active ==3;

15 semsignal(mutex);

17 /*临界区:对获得的资源进行操作 */

19 semwait(mutex);

20 --active;

21 if(active ==0)

29 must_wait = false;

31 semsignal(mutex);

这个程序看起来没有问题:所有对共享数据的访问均被临界区所保护,进程在临界区中执行时不会自己阻塞,新进程在有三个资源使用者存在时不能使用共享资源,最后一个离开的使用者会唤醒最多3个等待着的进程。

a.这个程序仍不正确,解释其出错的位置;

b.假如我们将第六行的if语句更换为while语句,是否解决了上面的问题?有什么难点仍然存在?

a.第29行直接让must_wait=false有问题,因为随后可能会有另一个新进程来访问资源,并在第六行判断为false,进而获取资源,而此时可能已经有3个等待的进程被唤醒,所以在同一时间内可能会有超过3个进程进入临界区。

b.可以解决上述问题,但是会有另一个缺陷,那就是先来的进程可能会在后来的进程之后获得资源,甚至有可能一直阻塞而饥饿。

总结:没有太大收获,总之互斥量mutex的p操作和v操作之间不会被其他进程所干扰,一次必须执行完。block操作不能在一个互斥量所保护的临界区中执行,即不能在临界区**现可能引起阻塞的过程,否则会发生死锁。

当某进程可能在等待过程中被后来进程插队进入临界区时,可能发生饥饿现象。

6、现在考虑上一题的正确解法,如下:

1 semaphore mutex = 1, block = 0;

2 int active = 0, waiting = 0;

3 boolean must_wait = false;

5 semwait(mutex);

6 if(must_wait) else

16 /*临界区:对获得的资源进行操作 */

18 semwait(mutex);

19 --active;

20 if(active ==0)

30 must_wait = active ==3;

32 semsignal(mutex);

a.解释这个程序的工作方式,为什么这种工作方式是正确的?

b.这个程序不能完全避免新到达的进程插到已有等待进程前得到资源,但是至少使这种问题的发生减少了。给出一个例子;

c.这个程序是一个使用信号量实现并发问题的通用解法样例,这种解法被称作“i'll do it for you”(由释放者为申请者修改计数器)模式。解释这种模式。

a.这个程序在释放的部分维护active的值,第 30行must_wait = active ==3;确保了等在block上的进程和新来的进程不会同时进入临界区。

b.仍然会有插队的情况,在一个进程执行完:

8 semsignal(mutex);

这一句但还没有执行:

9 semwait(block);

这时可能会有一个新的进程获取mutex,并阻塞在block上。如果此时有离开临界区的进程唤醒等在block上的进程,那么后来的进程可能会先执行,先来的进程却仍阻塞在block上。

c.i'll do it for you”由离开的进程来修改全局变量并唤醒阻塞的进程。这样被唤醒的进程不用再次判断全局条件是否满足。可以控制进程并发度。

7、现在考虑上一题的另一个正确解法,如下:

1 semaphore mutex = 1, block = 0;

2 int active = 0, waiting = 0;

3 boolean must_wait = false;

5 semwait(mutex);

6 if(must_wait)

12 ++active;

13 must_wait = active ==3;

14 if(waiting > 0 &&must_wait)

15 semsignal(block);

17 else semsignal(mutex);

19 /*临界区:对获得的资源进行操作 */

21 semwait(mutex);

22 --active;

23 if(active ==0) /只有在must_wait为true的时候才可能到这一步,这时候必须等所有进程全部释放资源。

24 must_wait = false;

25 if(waiting >=0 &&must_wait)

26 semsignal(block); 如果不是必须等待且有等待进程,则唤醒一个。

28 else semsignal(mutex);

a.解释这个程序的工作方式,为什么这种工作方式是正确的?

b.这个方法在可以同时唤醒进程个数上是否和上一题的解法有所不同?为什么?

c.这个程序是一个使用信号量实现并发问题的通用解法样例,这种解法被称作“pass the paton”(接力棒传递)模式。解释这种模式。

a.进程在释放资源时,如果此时释放的是最后一个被占用的资源,那么会唤醒一个等待在block上的进程(如果有的话),这个被唤醒的进程会判断是否还有等待在block上的进程并唤醒,直到有三个唤醒的进程。在这一过程中,新的申请资源的进程会等待在mutex上,而刚才第三个被唤醒的进程会唤醒等在mutex上的一个进程。

b.这个方法是唤醒一个进程,接着由该进程唤醒第二个进程,再由第二个进程唤醒第三个进程。之前的方法是由一个进程同时唤醒三个进程。

c.释放者只唤醒一个进程,然后被唤醒的进程负责唤醒下一个进程……直到唤醒所有等待的进程或唤醒的进程数量达到上限。接力棒模式能避免插队,但是在进程的并发性上不如“i'll do it for you”。

8、由于水面高度不同,有160~175米的落差,所以三峡大坝有五级船闸,t1~t5。由上游驶来的船需经由各级船闸到下游;由下游驶来的船需经由各级船闸到上游。假设只能允许单方向通行(此假设与实际情况不符,实际为双向各五级船闸)。

试用p、v操作正确解决三峡大坝船闸调度问题。

8、参***。

五级船闸,每级只能容纳一艘船。

一边已经有船等待时,另一边新来的船也不能出发。

int inside=0, up_waiting=0, down_waiting=0;

semaphore up_block=0, down_block=0, big_lock=1;

semaphore r[5] =船闸之间互斥。

void down()

down(big_lock)

if(up_waiting>0)

+down_waiting; /前面有船等待,则继续等待。

up(big_lock);

down(down_block);

else+inside;

up(big_lock);

/依次通过船闸,每个船闸最多容纳一艘船。

int i=0;

down(r[0]);申请通过第一级船闸。

while(i<4)

down(r[i+1]);

pass(i);

up(r[i]);只有当船过了下一级船闸才可以重新允许通过。

i++;up(r[4]);

down(big_lock);

-inside;

if(inside==0)

inside=up_waiting;

up_waiting=0;

for(int i=0; i

up(big_lock);

9、讲义上p、v操作的定义与教材上面的有区别。请问在程序中分别使用这两种定义,其效果有什么不同?能否在不改变程序意义的前提下,用一个代替另一个?

直接睡眠那个p操作,没有fifo的性质,依赖内核的调度器保证不会饥饿。系统的调度是全局的,一般保证调度的公平,但fifo就不能保证了。

大作业一Linux信号量机制v

1 需求说明。1.1 基本需求。目标 本次实验的目标是在linux环境下实现一个多线程对临界资源的互斥操作,利用信号量实现对临界资源的保护,支持linux下文件输入输出,提高对linux环境下多进程 多线程 信号量机制和文件操作等知识的理解。问题描述 设有进程a b c,分别调用过程get copy...

起重信号答案

施工人员安全教育培训标准化问答卷。起重工 信号作业 姓名日期成绩。1 信号工要持证上岗吗?2 吊物上可以站人吗?3 信号指挥可以用哪几种工具?4 吊索具由谁负责检查?5 信号工和挂钩工一起作业时由谁发号施令?6 在吊车大钩上焊一个挂钩可以吗?7 卡环出现裂纹,补焊后还可以使用吗?8 吊具包括什么?9...

信号 附上答案

广东海洋大学 2011 2012学年第二学期。信号与系统 课程试题。一 填空题 每空2分,共10分 1.从观察的初始时刻起不再施加输入信号,仅由该时刻系统本身具有的起始状态引起的响应称为 零输入响应。2.一个因果离散lti系统稳定的充要条件是 或全部极点都在单位圆内 3.1 t 5 4.设f1 n ...