本题为典型的生产者消费者问题,生产...
本题为典型的生产者消费者问题,生产者为顾客,消费者为营业员,缓冲区为座位区。
取号机只有一个资源,需要互斥访问,增加一个取号机的信号量,初始值为1,服务员叫号然后顾客接受服务为同步关系,增加一个服务的信号量,初始值为0。
补充说明:顾客i只会进银行一次,不会反复进银行,所以process 顾客i不需要while (TRUE) 死循环。营业员上班期间要时刻处于工作状态,所以process 营业员需要while (TRUE) 死循环。
很容易写出如下代码:
semaphore mutex = 1; // 座位区互斥信号量
semaphore empty = 10; // 座位区空闲位置数量
semaphore full = 0; // 座位区等待人的数量
semaphore service_i = 0; // 顾客i等待叫号
semaphore machine = 1; // 取号机
cobegin
process 顾客i {
P(empty);
P(machine);
从取号机获得一个号码;
V(machine);
P(mutex);
一位顾客进入座位区;
V(mutex);
V(full);
P(service_i); // 等待叫号
获得服务;
}
process 营业员 {
while (TRUE) {
P(full);
P(mutex);
一位顾客离开座位区;
V(mutex);
V(empty);
V(service_i);
叫号;
为顾客服务;
}
}
coend
由于service_i是针对某个顾客i的,如果是针对所有顾客,可以用散列表存储<服务号, 服务信号量>键值对,可以写出如下伪代码,更加方便理解。
semaphore mutex = 1; // 座位区互斥信号量
semaphore empty = 10; // 座位区空闲位置数量
semaphore full = 0; // 座位区等待人的数量
map<int, semaphore> service_map; // <服务号, 服务信号量>键值对映射表,初始为空
semaphore machine = 1; // 取号机
cobegin
process 顾客i {
P(empty);
P(machine);
从取号机获得一个号码x;
V(machine);
semaphore service_i = 0; // 生成顾客i的服务号对应的服务信号量
service_map[x] = semaphore service_i; // 将顾客i的<服务号, 服务信号量>存入<服务号, 服务信号量>键值对映射表
P(mutex);
一位顾客进入座位区;
V(mutex);
V(full);
P(service_i); // 等待叫号
获得服务;
}
process 营业员 {
while (TRUE) {
P(full);
P(mutex);
一位顾客离开座位区;
V(mutex);
V(empty);
叫号x;
semaphore service_i = service_map[x]; // 根据顾客i的服务号从<服务号, 服务信号量>键值对映射表获取顾客i的服务信号量
V(service_i);
为顾客服务;
service_map.erase(x); // 服务完成,从<服务号, 服务信号量>键值对映射表中移除该服务
}
}
coend
登录后提交答案
暂无评论,来抢沙发