系统调用中的信号量PV操作 理发师问题 联系客服

发布时间 : 星期日 文章系统调用中的信号量PV操作 理发师问题更新完毕开始阅读af8f18f74693daef5ef73d2c

? 理发师问题:一个理发店由一间等候室W和一间工作室B组成。顾客可以从外面大街上进入W等候理发。两个房间的入口是并排的,且共享一扇日本式可滑动的推拉门(门总是挡住一个入口)。顾客在工作室内理完发,可由B的旁门出去。W中有N把椅子,顾客必须坐着等候。理发师可由门上小窗查看W中无人就睡觉,否则开门,并叫一位顾客入内理发。顾客每进入一位,都拉铃通知理发师。若把顾客和理发师都视为进程,请用P、V操作写出进程的同步算法。 ? 要求打印:

题目中要求描述理发师和顾客的行为,因此需要两类线程barber()和customer ()分别描述理发师和顾客的行为。其中,理发师有活动有理发和睡觉两个事件;等待和理发二个事件。店里有固定的椅子数,上面坐着等待的顾客,顾客在到来这个事件时,需判断有没有空闲的椅子,理发师决定要理发或睡觉时,也要判断椅子上有没有顾客。所以,顾客和理发师之间的关系表现为:

(1)理发师和顾客之间同步关系:当理发师睡觉时顾客近来需要唤醒理发师为其理发,当有顾客时理发师为其理发,没有的时候理发师睡觉。

(2)理发师和顾客之间互斥关系:由于每次理发师只能为一个人理发,且可供等侯的椅子有限只有n把,即理发师和椅子是临界资源,所以顾客之间是互斥的关系。

(3)故引入3个信号量和一个控制变量:

ⅰ控制变量waiting用来记录等候理发的顾客数,初值为0;

ⅱ信号量customers用来记录等候理发的顾客数,并用作阻塞理发师进程,初值为0;

ⅲ信号量barbers用来记录正在等候顾客的理发师数,并用作阻塞顾客进程,初

值为1; ⅳ信号量mutex用于互斥,初值为1

using System;

using System.Collections.Generic; using System.Text;

using System.Threading;

namespace 理发师问题2 {

internal class Program {

// Fields

private static Semaphore barbers = new Semaphore(1, 10); private static int chairs; private static int count = 0;

private static Semaphore customers = new Semaphore(0, 10); private static int finish = 0;

private static Semaphore mtx = new Semaphore(1, 10); private static int waiting = 0;

// Methods

public static void barber() {

while (true) {

customers.WaitOne(); mtx.WaitOne(); waiting--;

barbers.Release(); mtx.Release(); cuthair(); finish++; } }

public static void customer() {

mtx.WaitOne(); count++;

Console.WriteLine(\叮咚!第{0}个顾客来了\, count); if (waiting < chairs) {

if (waiting > 0) {

Console.WriteLine(\此时有{0}个人在等待理发\, waiting);

} else {

Console.WriteLine(\没有人在等待\); }

waiting++;

Console.WriteLine(\还有{0}个座位,顾客留下\, (chairs - waiting) + 1);

mtx.Release();

customers.Release(); barbers.WaitOne(); gethaircut(); } else {

Console.WriteLine(\座位已满,第{0}个顾客离开\, count); mtx.Release(); } }

public static void cuthair() {

Console.WriteLine(\开始理发!这是理发师的第{0}个顾客.\, finish + 1);

Thread.Sleep(0x2328);

Console.WriteLine(\理发完成 !\); }

public static void gethaircut() {

Thread.Sleep(0x238c);

Console.WriteLine(\第{0}个顾客理发完毕,离开.\, finish); }

private static void Main(string[] args) {

string str = string.Empty;

Console.WriteLine(\请输入椅子的总数目:\); chairs = Convert.ToInt32(Console.ReadLine()); Console.WriteLine(\理发店共有{0}把椅子\, chairs); Console.WriteLine(\开门接待顾客吗?Y/N\); for (string str2 = Console.ReadLine(); (str2 != \) && (str2 != \); str2 = Console.ReadLine()) {

Console.WriteLine(\对不起,尚未开门!********\); Console.WriteLine(\开门接待顾客吗?Y/N\); }

Console.WriteLine(\营业中,欢迎光临!********\); new Thread(new ThreadStart(Program.barber)).Start(); while ((str != \) && (str != \)) {

Random random = new Random(DateTime.Now.Millisecond); Thread.Sleep(random.Next(1, 0x2710));

Console.WriteLine(\);

new Thread(new ThreadStart(Program.customer)).Start();

if ((finish >= 10) && (waiting == 0)) {

Console.WriteLine(\已经为{0}个顾客理发了,要关门下班吗?(Y/N)\, finish);

str = Console.ReadLine(); }

if ((str == \) || (str == \)) {

Console.WriteLine(\暂停营业!**********\);

break; } } } } }