用几道题作为今天学习的分享
如果有时间可以先试试做一下题再看我的理解
- 进程P0和P1并发执⾏,它们的共享变量定义及初值为:
boolean flag[2];
int turn=0;
flag[0]=false; flag[1]=false;
进程P0:
int x=0;
Thread1()
{
int a;
a=1;x+=1;
}
Thread2()
{
int a;
a=2;x+=2;
}
进程P1:
int x=0;
Thread3()
{
int a;
a=x; x+=3;
}
Thread4()
{
int b;
b=x; x+=4;
}
那么,上述代码能否保证两个进程互斥地进⼊临界区?会否出现“进程饥饿”现象?
我的理解是:
如果当就只有P0和P1两个进程时确实能,因为只要其中一个先执行了第一个语句,就能防止另一个进入临界区,但是若是第一个进程执行了第一个语句后系统将CPU资源分配给第二个进程执行第二个语句,就会出现两个进程都在等待的情况。即会出现“进程饥饿的现象。
2. 进程P0和P1均包含并发执⾏的线程,部分伪代码如下:
下列选项中,需要互斥执⾏的操作是()。
A. a=1 与 a=2; B. a=x 与 b=x; C. x+=1与x+=2; D. x+=1 与 x+=3.
答案好像应该选C,因为当系统在执行x+=1,时有两个过程,
第一个就是将x现在的值复制到CPU中的一个寄存器(因为要进行计算),在计算完之前,如果x+=3这一个语句要进行访问
读到的值是还是原来X的值,因为此时x+=1,这一个语句的计算结果还没重新对X进行赋值,这就导致系统出现两种结果,
比如x=0,x+=1,读取x=0,计算结果出来前,x+=2这个语句读取到的依旧是x=0,那么若x+=1,执行完,后x+=2,这个语句再对x进行赋值,最后x的值就只加了2,但是我们是想x加3的.
3. 某银⾏提供1个服务窗⼝和10个供顾客等待的座
位。顾客达到银⾏,若有空座位,则到取号机上领取
⼀个号,等待叫号。取号机每次仅允许⼀位顾客使
⽤,当营业员空闲时,通过叫号选取⼀位顾客为其服
务。顾客和营业员的活动过程描述如右。请添加必要
的信号量和P,V(或wait()和signal())操作,实现上述
过程中的互斥与同步。要求写出完整过程,说明信号
量的含义并赋初值。
parbegin
{
process customer
{
从取号机取号
等待叫号
获取服务
}
process server
{
while(true)
{
叫号;
为顾客服务
}
}
以下是我的粗浅的见解:
3. 分为两部分分析部分和伪代码部分
一、分析部分
4. //第一步进到店里,查看有无空座位且取号机是否空闲
5. //具体实现:用一个信号量代表座位的数量(10),一个信号量代表取号机是否空闲
6. // 对于座位的信号量:empty和full
7. // 操作一:每当一个顾客取完号,数量减一,
8. // 操作二:每当一个顾客被营业员服务时,数量加一。
9. //对于取号机的信号量:mmutex
10. //操作一: 顾客取号时,减一
11. // 操作二:顾客取完号,加一
12. // 第二步进入等待
// 第三步当营业员有空闲时,停止等待。
//首先我们在前面两个信号量的基础上上,我们只需要一个信号量来代表营业员是否空闲就行。
// 对于营业员的信号量:smutex
// 操作一:若有顾客在等待,数量减一。
// 操作二:服务完,数量加一。
二、伪代码部分
Parbegin//包括三个实体,取号机,顾客,营业员
{
Type
13. semaphore=record
14. Value:integer;
15. L:list of process;
16. Var empty,full,mmutex,smutex:semaphore:=10,0,1,1;
17. Procedure Swait(S1,S2)
18. {
19. If S1>0 and S2>0 then
20. for i:=1 to n do
21. Si:=Si-1;
22. Endfor
23. Else
24. Place the process in the waiting queue associated with the first Si found with Si<0
25. endif
26. }
27. Procedure signal(S)
28. {
29. Var S:semaphore;
30. Begin
31.
32. S.value:=S.value+1;
33. Remove all the process waiting in the queue associated with Si into the ready queue
34. end
35. }
36. Procedure Ssignal(S1,S2)
37. {
38. For i:=1 to n do
39. Si:=Si+1;
40. Remove all the process waiting in the queue associated with Si into the ready queue
41. Endfor;
42. }
43.
44. Procedure customer
45. {
46.
47. Swait(empty,mmutex);
从取号机取号;
Ssignal(full,mmutex);//进入空闲,且将full加一,意味着有人在等待了
Swait(full,smutex);
Signal(empty);//此时座位应该多一个
获取服务
Signal(smutex); //进入空闲
48.
49.
50. }
51. Procedure server
52. {
53. While(true)
54. {
55. Swait(full,smutex);
56. Signal(empty);//此时座位应该多一个
57. 叫号;
58. 为顾客服务;
Signal(smutex);//进入空闲状态
59. }
60. }
}
4.某自动质量检测系统有三个进程A、B、C组成。
进程A每次取一件产品检测,把检测后的产品存放在货架F上,F的容量为每次只能存放一件产品。
若货架上存放的是合格产品则让进程B取出,并在产品上贴标签后包装;
若货架上存放的是不合格产品则让进程C取出后,将其丢入废物箱。
//首先我们将解题过程分为两个部分,第一部分为分析的部分
//首先题目中有一个中心词就是产品,所有的操作都是围绕产品进行的。
//抽象来说,1.产品检测()->放货架F(容量为1)信号量 rmutex
// 2.检测货物合格与否,先将(这里需要互斥)容量减一,然后执行B或C程序
信号量的同步方式:
Parbegin
{
Type
1. semaphore=record
2. Value:integer;
3. L:list of process;
4. Var empty,full:semaphore:=1,0;
5. Procedure wait(S)
6. Var S:semaphore;
7. Begin
8.
9. S.value:=S.value-1;
10. If S.value<0 then
11. block(S.L);
12. end
13.
14. Procedure signal(S)
15.
16. Var S:semaphore;
17. Begin
18.
19. S.value:=S.value+1;
20. If S.value<=0 then
21. wakeup(S.L);
22. end
23.
24. Procedure A
25.
26. begin
27. 检测产品的质量
28. Wait(empty);//将信号量减一,如果小于0那么进入等待序列
29. 放上货架
30. Signal(full);
31. end
32.
33. Procedure B
34.
35. begin
36.
37. Wait(full);
38. Signal(empty);
39. 取出产品并为产品贴上标签
40. end
41.
42. Procedure C
43.
44. begin
45. Wait(full);
46. Signal(empty);
47. 取出产品丢进垃圾桶;
48.
49. end
50.
51.
}
管程的进程同步
Parbegin
{
Type PC=monitor
Full,empty:condition;
Procedure A;
Procedure B;
Procedure C;
Use monitor.wait,monitor.signal;
Begin
count:=0;
end;
procedure A
begin
检测产品
if count>=1 then full.wait;
放到货架上
count:=count+1;
if empty.queue then empty.signal;
end
procedure B
Begin
If count<=0 then empty.wait;
Count:=count-1;
If full.queue then full.signal;
为产品贴上标签
end
procedure C
Begin
If count<=0 then empty.wait;
Count:=count-1;
If full.queue then full.signal;
丢进废物箱
end
}
若有不对的地方请指出,谢谢大佬。