第一部分。
该方法对可抢占调度完全没问题。事实上,它就是为这种情况设计的。当调度为不可抢占的,该方法将会失败。假设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 ...