进程互斥访问&同步问题综合

1窗口n客人叫号

面包师有很多面包,由n名销售人员卖。每个客人进店后取号,并等待叫号。当一名销售人员空闲,就叫下一个号。

n个销售【服务窗口】,n个客人

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
int waitnum=0;//取号值
int servernum=0;//叫号值
semaphore mutex_waitnum=1,mutex_servernum=1;//用来保证修改num过程是原子性

//mutex_waitnum和mutex_servernum只是锁
//waitnum作为状态变量
customer{
while(1){
P(mutex_waitnum);
//取号
waitnum+=1;
V(mutex_waitnum);
}
}

server{
while(1){
P(mutex_servernum);
if(waitnum<servernum){
servernum+=1;
}
V(mutex_servernum);
}
}

//方法2:完全使用PV操作
semaphore mutex=1;//锁:锁取号机
customer{
P(mutex);
取号
V(mutex);
V(customer);//告诉服务人员,来人了
P(server);//等待服务
被服务函数
}

server{
P(customer);//消耗一个客人
V(server);//提供服务
服务函数
}

1窗口n客人M椅子,人会离开

理发店里面一位理发师,一把理发椅子和n个等待时椅子。若没有客人,理发师在理发椅子上睡觉。若有客人,客人要叫醒理发师,若理发师在理发又有客人来,若椅子有空,客人在椅子上等待,椅子不空就离开。使用PV操作

本题中,椅子不空就离开。说明不是进程不是一直等待下去,不能直接用P操作,因为P操作会一直等待。需要用状态变量+锁的方式完成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
int wait=0,chair=n;
semaphore mutex_wait=1;//锁
semaphore server=0;//表示需要服务数
semaphore customer=0;//表示客人数量

//和第一题方法2相似
customer{
P(mutex_wait);
if(wait<chair){
wait+=1;
V(customer);//告诉服务人员,来人了
V(mutex);
P(server);//等待服务
被理发函数
}
else{
V(mutex_wait);
}
}

barber{
P(customer);//如果有客人就提供服务,没有就睡觉
P(mutex_wait);
wait-=1;
V(server);//理发师醒了
V(mutex_wait);
理发函数
}

1窗口n客人M椅子,人不离开

银行提供一个服务窗口和10个等待座位。客人到达银行时,若有空位,则到取号机拿号并坐下等待。否则就一直等待空座位再拿号。取号机每次仅允许一个人使用。营业员空闲时,叫号一个客人并服务。

本题中,椅子不空就等待,可以使用PV

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
semaphore chair=10;//固定资源
semaphore mutex=1;//锁
semaphore customer=0;
semaphore server=0;

customer{
P(chair);//有椅子就拿号,没椅子就等。不像第二题会走
P(mutex);//叫号机上锁
取号函数
V(mutex);
V(customer);//告诉服务人员,来人了
P(server);//等待服务
被服务函数
}

server{
P(customer);//消耗一个客人
V(chair);//空出一个椅子
V(server);//提供服务
服务函数
}

双资源生产者问题

小和尚,老和尚若干。有一个水缸,只能小和尚提水给老和尚用。水缸可以容10桶水,水取自同一个水井。水井每次只能由一桶水,一共有3个水桶。水缸一次只能入一桶水。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
semaphore mutex_shaft=1;//水井
semaphore mutex_tank=1;//水缸
semaphore bucket=3;//资源
semaphore tank_empty=10;//经典生产者和消费者的条件变量
semaphore tank_full=0;

老{
P(tank_full);
P(bucket);
P(mutex_tank);
取水
V(mutex_tank);
V(bucket);
V(tank_empty);//提醒生产者生产
}

小{
P(tank_empty);
P(bucket);
P(mutex_shaft);
从水井打水
V(mutex_shaft);
//再向水缸放水
P(mutex_tank);
放水
V(mutex_tank);
V(bucket);
V(tank_full);//提醒消费者消费
}

多进程同步问题

三个合作进程P1,P2,P3。者通过同一个设备输入各自的数据a,b,c。输入设备互斥使用。a为第一个输入必须由P1读取。b为第二个输入必须由P2读取。c为第二个输入必须由P3读取。然后进行以下运算

P1:x=a+b;

P2:y=a*b;

P3:z=y+c-a;

最后,由P1通过打印机将x,y,z打印出来。

因为规定了P1先取a,P2再取b,P3最后取C。设置fetch_a=1;fetch_b=0;fetch_c=0;表示a可以取

P1需要等待P2读取b,则有个信号量b_done

P3需要等待P2计算出y,则有个信号量y_done

P1最后需要等待P3计算出z,则有个信号量z_done

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
semaphore fetch_a=1;
semaphore fetch_b=1;
semaphore fetch_c=1;

P1{
P(fetch_a);
取a数据
V(fetch_b);//允许P2读取b
P(b_done);//在P2得到b之前,P1要等待
x=a+b;
P(z_done);//在P3得到z之前,P1要等
打印x,y,z//因为z也需要y,所以P1不用等y
}

P2{
P(fetch_b);
取b数据
V(fetch_c);//允许P3读取c
y=a*b;
V(y_done);//唤醒等待y的进程
}

P3{
P(fetch_c);
取c数据
P(y_done);//等待y
z=y+c-a;
V(z_done);//唤醒等待z的进程
}

未完……