- •Курсовая работа
- •Аннотация
- •Введение
- •2.Практическая часть
- •2.1. Постановка задачи
- •2.2. Алгоритмическое решение задачи с использованием сетей Петри Представлена сеть Петри для 5 философов (Рисунок 3) ----------------
- •2.3. Решение задачи в программных кодах
- •2.3.1. Программный код приложения «Философ»
- •2.3.2 Программный код приложения «Стол»
- •2.4. Пример работы программы
- •2.5. Выводы по практической части
- •Заключение
- •Список использованных источников
2.Практическая часть
2.1. Постановка задачи
Исходные данные для задачи: представим себе парк, по аллеям которого прогуливаются N философов. В центре парка расположена столовая, в которой накрыт круглый стол. В центре стола стоит миска с рисом, а вокруг неё расположены N тарелок и N палочек. Если философ проголодался (это происходит за определенный промежуток времени для каждого философа), он входит в столовую, занимает свободное место за столом, накладывает себе в тарелку рис, берет две палочки и принимается за еду. Затем философ некоторое неопределённое время кушает. Утолив голод, философ возвращает палочки на стол и покидает столовую. В случае если все N философов одновременно придут в столовую, займут все места за столом и возьмут по палочке, система окажется заблокированной, т.к. ни один из философов не сможет приступить к еде.
Требуется организовать систему таким образом, чтобы N философов не могли одновременно оказаться за столом, и чтобы была невозможна ситуация, когда каждый философ взял по 1 палочке и никто не может взять вторую. Задачу решить через организацию межпроцессного взаимодействия.
Схематическое изображение задачи − Рисунок 2
Рисунок 2.
2.2. Алгоритмическое решение задачи с использованием сетей Петри Представлена сеть Петри для 5 философов (Рисунок 3) ----------------
Рисунок 3.
2.3. Решение задачи в программных кодах
2.3.1. Программный код приложения «Философ»
//Основной код работы философа
while(true)
{//значение семафора: 1 - философ ест, 2 - гуляет, 3- гуляет и голоден
walk();
WaitForSingleObject(mutex,INFINITI); //ожидание мьютекса на палочки
fixed (uint* adr_sticks = &sticks)
{ ReleaseSemaphore(SemathorSticks, 1, adr_sticks); } //считывем количество палочек
WaitForSingleObject(SemathorSticks, INFINITI);
if (sticks >= 2) //при истиности условия
{
WaitForSingleObject(SemathorSticks, INFINITI);
WaitForSingleObject(SemathorSticks, INFINITI);
//уменьшаем на 2 палочки
ReleaseMutex(mutex); //отпускаем мьютекс - палочки
eating();
}
else
{// если не хватает палочек, философ уходит гулять голодным
ReleaseMutex(mutex);
WaitForSingleObject(Philmutex, INFINITI);
if(MyState != "Walking and Hungry")
ReleaseSemaphore(SemathorState, 1, null);
MyState = "Walking and Hungry";
ReleaseMutex(Philmutex);
label.Invoke(new Action(() => { label.Text = "Philosopher " + number.ToString() + ": " + MyState; }));
}
}
}
public void walk()
{
Thread.Sleep(rand.Next(2500,3000));
}
public void eating()
{//уведомляем сервер о состоянии eating
WaitForSingleObject(Philmutex, INFINITI);
if (MyState == "Walking") //переводим в состояние "ем" //семафор состояния
{
WaitForSingleObject(SemathorState, INFINITI);
}
else
if (MyState == "Walking and Hungry")
{ //если до того как поесть, философ был "Walking and Hungry" //уменьшаем семафор с 3 до 1
WaitForSingleObject(SemathorState, INFINITI);
WaitForSingleObject(SemathorState, INFINITI);
}
ReleaseMutex(Philmutex);
MyState = "Eating";
label.Invoke(new Action(() => { label.Text = "Philosopher " + number.ToString() + ": " + MyState; }));
Thread.Sleep(rand.Next(3000, 4000));
WaitForSingleObject(mutex, INFINITI);
WaitForSingleObject(Philmutex, INFINITI);
ReleaseSemaphore(SemathorSticks, 2, null);
//после того как поел, философ возвращает палочки
ReleaseSemaphore(SemathorState, 1, null);
//и переходит в состояние «гуляю»
MyState = "Walking";
ReleaseMutex(Philmutex);
ReleaseMutex(mutex);
label.Invoke(new Action(() => { label.Text = "Philosopher " + number.ToString() + ": " + MyState; }));
}