![]() |
1. Пользуйтесь тегами кода. - [code] ... [/code]
2. Точно указывайте язык, название и версию компилятора (интерпретатора).
3. Название темы должно быть информативным.
В описании темы указываем язык!!!
![]() ![]() |
![]() |
Unknown |
![]()
Сообщение
#1
|
![]() Пионер ![]() ![]() Группа: Пользователи Сообщений: 104 Пол: Мужской Реальное имя: Евгений Репутация: ![]() ![]() ![]() |
Проблема спящего брадобрея
Действие еще одной классической проблемной ситуации межпроцессного взаимодействия разворачивается в парикмахерской. В парикмахерской есть один брадобрей, его кресло и п стульев для посетителей. Если желающих воспользоваться его услугами нет, брадобрей сидит в своем кресле и спит. Если в парикмахерскую приходит клиент, он должен разбудить брадобрея. Если клиент приходит и видит, что брадобрей занят, он либо садится на стул (если есть место), либо уходит (если места нет). Необходимо запрограммировать брадобрея и посетителей так, чтобы избежать состояния состязания. У этой задачи существует много аналогов в сфере массового обслуживания, например информационная служба, обрабатывающая одновременно ограниченное количество запросов, с компьютеризированной системой ожидания для запросов. Это задание. Возник вопрос не совсем относящийся к теме: есть ли аналог глобальных переменных в С#? т.е. мне нужно, чтобы переменная, обозначающая кол-во посетителей, была доступна во всей программе. В дальнейшем, думаю, вопросы еще возникнут - вот и создал тему. -------------------- go ask Alice
|
hardcase |
![]()
Сообщение
#2
|
![]() code warrior ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 484 Пол: Мужской Реальное имя: Славен Репутация: ![]() ![]() ![]() |
Проблема спящего брадобрея... Это задание. Возник вопрос не совсем относящийся к теме: есть ли аналог глобальных переменных в С#? т.е. мне нужно, чтобы переменная, обозначающая кол-во посетителей, была доступна во всей программе. Статическое свойство класса тебе поможет. Код public class Barbery { private static int _client_count = 0; public static int ClientCount { get { return _client_count; } } } Кстати C# имеет собственный механизм синхронизации: Код lock(some_object) { } где some_object - это экземпляр ссылочного типа. Синхронизация основана на механизме монитора (эквивалентно семафору). Сообщение отредактировано: hardcase - 27.04.2008 11:19 -------------------- ИзВ ин ИтЕ зА нЕ рОв НЫй П оч ЕРк
|
Unknown |
![]()
Сообщение
#3
|
![]() Пионер ![]() ![]() Группа: Пользователи Сообщений: 104 Пол: Мужской Реальное имя: Евгений Репутация: ![]() ![]() ![]() |
Цитата Статическое свойство класса тебе поможет. точно! туплю )) а по поводу lock'а в курсе, спасибо ![]() -------------------- go ask Alice
|
Unknown |
![]()
Сообщение
#4
|
![]() Пионер ![]() ![]() Группа: Пользователи Сообщений: 104 Пол: Мужской Реальное имя: Евгений Репутация: ![]() ![]() ![]() |
В общем, вот, что у меня получилось:
Код using System; using System.Threading; class Barber { public static int barbers = 1; public static int chairs = 5; public static int customers = 0; public static Random r = new Random(); class Customer { public bool served; public Thread thrd; public Customer(string name) { served = false; thrd = new Thread(new ThreadStart(this.run)); thrd.Name = name; thrd.Start(); } public void run() { Console.WriteLine(thrd.Name + " пришел."); do { if (barbers > 0) //брадобрей свободен { barbers--; served = true; } else { //брадобрей занят if (customers < chairs) customers++; //клиент ждет else { Console.WriteLine(thrd.Name + " ушел."); return; //клиент ушел(нет мест) } } customers--; } while (!served); Console.WriteLine(thrd.Name + " обслуживается."); Thread.Sleep(500); customers--; barbers++; Console.WriteLine(thrd.Name + " обслужен."); } } class MultiThread { public static void Main() { Customer c1 = new Customer("Клиент #1"); Customer c2 = new Customer("Клиент #2"); Customer c3 = new Customer("Клиент #3"); Customer c4 = new Customer("Клиент #4"); Customer c5 = new Customer("Клиент #5"); Console.ReadKey(); } } } Вроде все работает как задумано - это нормальное решение? Сообщение отредактировано: Unknown - 27.04.2008 19:07 -------------------- go ask Alice
|
Гость |
![]()
Сообщение
#5
|
Гость ![]() |
Помоему полная фигня
![]() Да и нет идеи "пробуждения брадобрея". Вот мой пример, в котором, однако, тоже нет пробуждения. Для этого нужно вместо слипа вешаться на WaitHandle, а клиенты должны его дёргать по приходу. Код using System; using System.Collections.Generic; using System.Linq; using System.Threading; static class BarberRoom { public static void Main() { new Client("Клиент #1"); new Client("Клиент #2"); new Client("Клиент #3"); new Client("Клиент #4"); new Client("Клиент #5"); new Barber("Брадобрей #1"); new Barber("Брадобрей #2"); Console.ReadKey(); } static List<Client> _clientsOnChairs = new List<Client>(); const int ChairsCount = 5; static Random rnd = new Random(); class Client { public bool Served; public bool Serving; public Client(string name) { Name = name; var th = new Thread(delegate() { if (tryTakeChair()) { while (!Served) { Console.WriteLine(name + " ждёт"); Thread.Sleep(500); } Console.WriteLine(name + " обслужен"); lock (_clientsOnChairs) { _clientsOnChairs.Remove(this); } } else { Console.WriteLine(name + " ушел, нет места..."); } }); th.IsBackground = true; th.Name = "Client: " + name; th.Start(); } public string Name { get; private set; } bool tryTakeChair() { lock (_clientsOnChairs) { if (_clientsOnChairs.Count < ChairsCount) { _clientsOnChairs.Add(this); return true; } } return false; } } class Barber { Client tryGetClient() { lock (_clientsOnChairs) { var client = _clientsOnChairs.FirstOrDefault(x => !x.Serving); if (client != null) client.Serving = true; return client; } } public Barber(string name) { var th = new Thread(delegate() { while (true) { var client = tryGetClient(); if (client != null) { Console.WriteLine(name +" обслуживает "+client.Name); Thread.Sleep(500 + rnd.Next(1000)); client.Served = true; Console.WriteLine(name + " закончил"); } else { Console.WriteLine(name + " спит"); Thread.Sleep(5000); Mutex } } }); th.IsBackground = true; th.Name = "Barber: " + name; th.Start(); } } } |
![]() ![]() |
![]() |
Текстовая версия | 23.07.2025 14:48 |