Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Мязитов Роберт ОС.docx
Скачиваний:
2
Добавлен:
01.05.2025
Размер:
349.93 Кб
Скачать

Практическое задание

  1. Описание программы

Процессы называются параллельными, если они существуют одновременно.

Процессы называются асинхронными, если они могут работать независимо друг от друга. В противном случае - они называются синхронными.

Взаимоисключение - ситуация, когда один процесс, обращаясь к разделяемым (общим) данным, исключает для другого(их) процесса(ов) возможность одновременного к ним обращения.

Критический участок - участок процесса (область программы), на котором обращение к общим ресурсам (данным) приводит к конфликтным ситуациям.

Один из способов реализации ситуации взаимоисключения - алгоритм Деккера.

Пусть имеются 2 флага - f1 и f2 - принимающие значения 0 или 1. Первый флаг (f1) выставляет процесс 1 (значение f1 := 1), когда ему требуется войти в критический участок. При выходе процесса 1 из критического участка (или в случае отказа от намерения войти в критический участок) флаг f1 сбрасывается (f1 := 0). Процесс 2 проделывает аналогичные действия с флагом f2 при намерении войти в критический участок (f2 := 1) и при выходе из него или при отказе от намерения войти в критический участок (f2 :=0).[Методические указания по лабораторным работам Шалагин С.В.]

  1. Листинг программы

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading;

using System.Windows.Forms;

using System.Text;

public static class GlobPer // Глобальные переменные

{

public static int f1 = 0, f2 = 0, izp = 0, z = 0;

public static string r;

static int n = 0;

public static void Read()

{

if (n == 0)

{

n++;

do

{

r = Console.ReadLine();

}

while (r != "1" && r != "2");

n--;

}

}

}

public static class Resurs // Критический участок

{

public static int i = 0; // Счетчик кр. участка

public static void F(int P)

{

++i;

Console.WriteLine("Процесс " + P + " записал в кр. участок, счетчик = " + i);

}

}

class Sost : Form

{

RichTextBox rt;

public Sost()

{

this.Text = "Состояние";

rt = new RichTextBox();

rt.Multiline = true;

rt.ScrollBars = RichTextBoxScrollBars.ForcedBoth;

rt.Dock = DockStyle.Fill;

rt.ReadOnly = true;

Controls.Add(rt);

Show();

}

public void SetSt(string st)

{

st = Environment.NewLine + st;

rt.AppendText(st);

rt.ScrollToCaret();

}

}

namespace Prog1

{

delegate void Del(string text);

class Process

{

Thread T;

Sost S;

public Process()

{

System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;

S = new Sost();

S.Text = "Процесс 1";

T = new Thread(new ThreadStart(ThreadRun));

T.Start();

}

void Susp()

{

GlobPer.Read();

while (GlobPer.r != "1")

{

Thread.Sleep(100);

}

GlobPer.r = "0";

}

public void ThreadRun()

{

while (Resurs.i < 10)

{

GlobPer.f1 = 1; //Производится уведомление о намерении войти в критический участок

// S.Invoke()

S.SetSt("Процесс 1 установил флаг входа");

S.SetSt("Для продолжения работы процесса нажмите 1");

Susp();

S.SetSt("Процесс 1 проверяет флаг входа процесса 2");

if (GlobPer.f2 == 0)

{

S.SetSt("Процесс 2 не намерен войти в критический участок");

S.SetSt("Процесс 1 входит в критический участок");

GlobPer.z = 1;

Resurs.F(1); //критический участок

S.SetSt("Для выхода процесса из кр. участка нажмите 1");

Susp();

GlobPer.z = 0;

S.SetSt("Процесс 1 вышел из критического участка");

}

else

{

S.SetSt("Оба процесса намерены войти в критический участок");

if (GlobPer.z == 0)

{

if (GlobPer.izp == 1)

{

S.SetSt("Процесс 1 - избранный");

S.SetSt("Процесс 1 входит в критический участок");

GlobPer.z = 1;

Resurs.F(1); //критический участок

S.SetSt("Для выхода процесса из кр. участка нажмите 1");

Susp();

GlobPer.z = 0;

S.SetSt("Процесс 1 вышел из критического участка");

}

}

else

{

S.SetSt("Процесс ожидает освобождения кр. участка");

while (GlobPer.z != 0)

{

Thread.Sleep(100);

GlobPer.Read();

}

S.SetSt("Процесс 1 входит в критический участок");

GlobPer.z = 1;

Resurs.F(1); //критический участок

S.SetSt("Для выхода процесса из кр. участка нажмите 1");

Susp();

GlobPer.z = 0;

S.SetSt("Процесс 1 вышел из критического участка");

}

}

GlobPer.f1 = 0; //отказывается от намерения в него войти

S.SetSt("Процесс 1 снял флаг");

S.SetSt("Для продолжения работы процесса нажмите 1");

Susp();

}

}

}

}

namespace Prog2

{

class Process

{

Thread T;

Sost S;

public Process()

{

System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;

S = new Sost();

S.Text = "Процесс 2";

T = new Thread(new ThreadStart(ThreadRun));

T.Start();

}

void Susp()

{

GlobPer.Read();

while (GlobPer.r != "2")

{

Thread.Sleep(100);

}

GlobPer.r = "0";

}

public void ThreadRun()

{

while (Resurs.i < 10)

{

GlobPer.f2 = 1; //Производится уведомление о намерении войти в критический участок

S.SetSt("Процесс 2 установил флаг входа");

S.SetSt("Для продолжения работы процесса нажмите 2");

Susp();

S.SetSt("Процесс 2 проверяет флаг входа процесса 1");

if (GlobPer.f1 == 0)

{

S.SetSt("Процесс 1 не намерен войти в критический участок");

S.SetSt("Процесс 2 входит в критический участок");

GlobPer.z = 1;

Resurs.F(2); //критический участок

S.SetSt("Для выхода процесса из кр. участка нажмите 2");

Susp();

GlobPer.z = 0;

S.SetSt("Процесс 2 вышел из критического участка");

}

else

{

S.SetSt("Оба процесса намерены войти в критический участок");

if (GlobPer.z == 0)

{

if (GlobPer.izp == 2)

{

S.SetSt("Процесс 2 - избранный");

S.SetSt("Процесс 2 входит в критический участок");

GlobPer.z = 1;

Resurs.F(2); //критический участок

S.SetSt("Для выхода процесса из кр. участка нажмите 2");

Susp();

GlobPer.z = 0;

S.SetSt("Процесс 2 вышел из критического участка");

}

}

else

{

S.SetSt("Процесс ожидает освобождения кр. участка");

while (GlobPer.z != 0)

{

Thread.Sleep(100);

GlobPer.Read();

}

S.SetSt("Процесс 2 входит в критический участок");

GlobPer.z = 1;

Resurs.F(2); //критический участок

S.SetSt("Для выхода процесса из кр. участка нажмите 2");

Susp();

GlobPer.z = 0;

S.SetSt("Процесс 2 вышел из критического участка");

}

}

GlobPer.f2 = 0; //отказывается от намерения в него войти

S.SetSt("Процесс 2 снял флаг");

S.SetSt("Для продолжения работы процесса нажмите 2");

Susp();

}

}

}

}

public class MainClass

{

public static void Main()

{

if (GlobPer.izp == 0)

{

Console.WriteLine("Введите приоритет 1 или 2");

GlobPer.Read();

if (GlobPer.r == "1") { GlobPer.izp = 1; GlobPer.r = "0"; }

else { GlobPer.izp = 2; GlobPer.r = "0"; }

}

new Prog1.Process();

new Prog2.Process();

Application.Run();

}

}