
- •Курсовая работа по дисциплине «Операционные системы вычислительной техники» группа атп-41
- •1 Задания на курсовую работу
- •2 Пояснения к поставленной задаче
- •Вариант № 1
- •Вариант № 2
- •Вариант № 3
- •Вариант № 4
- •Вариант № 5
- •Вариант № 6
- •Вариант № 7
- •Вариант № 8
- •Вариант № 9
- •Вариант № 10
- •3 Алгоритм решения задачи
- •Описание методов решения и алгоритмов задач, реализуемых каждым потоком
- •4 Требования к пояснительной записке
- •4.1 Оформление пояснительной записки
- •Барановичи год
- •Министерство образования республики беларусь учреждение образования «барановичский государственный университет»
- •Глава 1. Теоретическая часть
- •Глава 2. Практическая часть
- •Список использованных источников
Описание методов решения и алгоритмов задач, реализуемых каждым потоком
В основной программе вводим размер массива N и время вывода T.
Работа первого потока заключается в следующем:
Ждем время T;
Если заполнили весь массив – переходим к п.9;
Входим в критическую секцию;
Увеличиваем размер массива;
Добавляем случайный элемент;
Выводим элемент;
Выходим из критической секции;
Переходим к п. 2;
Завершаем поток.
Работа второго потока заключается в следующем:
1. Если дошли до конца массива – переходим к п. 7;
2. Если требуемые элементы еще не заполнены потоком A – п. 2 (ждем);
3. Берем два подряд идущих числа. Считаем их x и y;
4. Рассчитываем расстояние до начала координат. Накапливаем расстояние;
5. Выводим среднее расстояние из уже рассчитанных;
6. Наращиваем счетчик на 2. Переходим к п.1;
7. Завершаем поток.
Работа третьего потока заключается в следующем:
1. Если дошли до конца массива – переходим к п. 7;
2. Если требуемые элементы еще не заполнены потоком A – п. 2 (ждем);
3. Берем текущий элемент массива и находим минимальное и максимальное значение между ним и уже найденными до сих пор;
4. Рассчитываем процент;
5. Выводим Min, Max и процент;
6. Наращиваем счетчик на 1. Переходим к п. 1;
7. Завершаем поток.
Описание методов создания, синхронизации и уничтожения потоков
Поток А.
Класс потока имеет следующую структуру.
TAThread = class(TThread)
public
constructor Create(CreateSuspended: Boolean);
destructor Destroy; override;
protected
procedure Execute; override;
end;
Создание потока осуществляется в конструкторе Create, параметром которого служит переменная CreateSuspended, позволяющая сразу запустить поток или оставаться в приостановленном состоянии.
В конструкторе совершаются следующие действия.
constructor TAThread.Create(CreateSuspended: Boolean);
begin
inherited; // Запуск родительского конструктора
SetLength(Mas, 0); // Подготовка массива
Randomize; // Инициализация случайных чисел
end;
В деструкторе происходят следующие действия.
destructor TAThread.Destroy;
begin
SetLength(Mas, 0); // Удаление массива из памяти
Mas := nil;
inherited; // Вызов родительского деструктора
end;
В процедуре обработки потока происходят следующие действия.
procedure TAThread.Execute;
begin
repeat
Sleep(T); // Устанавливаем задержку в мс
if Length(Mas) < N then // Если не превысили размер массива
begin
Section.Enter; // Входим в критическую секцию
SetLength(Mas, Length(Mas) + 1); // Увеличиваем размер массива
Mas[Length(Mas) - 1] := -999 + Random(1999); //Заносим случайное число
GotoXY(0, Length(Mas) + 4); //Устанавливаем курсор в нужную позицию
Write(Mas[Length(Mas) - 1]: 4); // Выводим элемент
Section.Leave; // Выходим из критической секции
end
else
Terminate; // Если превышен размер массива – завершаем поток
until Terminated;
end;
Здесь необходима критическая секция, так как в этом фрагменте изменяется размер массива, который используется потоками B и C. Поэтому важно не допустить эти потоки к массиву, пока он изменяется, чтобы избежать случаев, когда размер массива изменен, а, например, новое число в него еще не внесено.
Поток B.
Класс потока имеет следующую структуру.
TBThread = class(TThread)
public
constructor Create(CreateSuspended: Boolean);
protected
procedure Execute; override;
end;
Создание потока осуществляется в конструкторе Create, параметром которого служит переменная CreateSuspended, позволяющая сразу запустить поток или оставаться в приостановленном состоянии.
В конструкторе совершаются следующие действия.
constructor TBThread.Create(CreateSuspended: Boolean);
begin
inherited; // Запуск родительского конструктора
CurB := 0; // Устанавливаем текущую позицию в массиве
Dist := 0; //Подготавливаем переменную для хранения расстояний
end;
В процедуре обработки потока происходят следующие действия.
procedure TBThread.Execute;
begin
repeat
if CurB = N then // Если дошли до конца массива – завершаем работу
Terminate;
if CurB <= Length(Mas) - 2 then // Следуем по массиву с шагом два (координата x и y)
begin
{ Вычисляе расстояние от точки до начала координат }
Dist := Dist + Sqrt(Sqr(Mas[CurB]) + Sqr(Mas[CurB + 1]));
{ Выводим }
GotoXY(15, CurB + 6); Write('Dist=', Dist / (CurB + 2): 6: 4);
{ Переходим к следующим координатам }
Inc(CurB, 2);
end;
until Terminated;
end;
Поток C.
Класс потока имеет следующую структуру.
TCThread = class(TThread)
public
constructor Create(CreateSuspended: Boolean);
protected
procedure Execute; override;
end;
Создание потока осуществляется в конструкторе Create, параметром которого служит переменная CreateSuspended, позволяющая сразу запустить поток или оставаться в приостановленном состоянии.
В конструкторе совершаются следующие действия.
constructor TBThread.Create(CreateSuspended: Boolean);
begin
inherited; // Запуск родительского конструктора
CurC := 0; // Устанавливаем текущую позицию в массиве
Max := -1000; // Настраиваем Min и Max. Ставим для Max заведомо меньшее из чисел, а для Min – заведомо большее
Min := 1000;
end;
В процедуре обработки потока происходят следующие действия.
procedure TBThread.Execute;
var
Proc: double;
begin
repeat
if CurC = N then // Если достигнут конец массива – завершаем поток
Terminate;
if CurC < Length(Mas) then // Не должны считать элементы, которые еще не заполнены.
begin
Inc(CurC);
{ Находим Min и Max среди уже найденных и текущим элементом}
if Min > Mas[CurC - 1] then
Min := Mas[CurC - 1];
if Max < Mas[CurC - 1] then
Max := Mas[CurC - 1];
if Max = Min then
Proc := 0 // Для первого элемента = 0, так как изначально Min=Max
else
Proc := Mas[CurC - 1] / (Max - Min);
{ Выводим }
GotoXY(35, CurC + 4); Write('Max=', Max: 4);
GotoXY(50, CurC + 4); Write('Min=', Min: 4);
GotoXY(65, CurC + 4); Write('Proc=', Abs(Proc * 100):6:3, '%');
end;
until Terminated;end;
В основной программе мы создаем объекты-потоки.
ThreadA := TAThread.Create(true);
ThreadB := TBThread.Create(true);
ThreadC := TCThread.Create(true);
Указываем на то, что после завершении потока они должны быть удалены их памяти.
ThreadA.FreeOnTerminate := true;
ThreadB.FreeOnTerminate := true;
ThreadC.FreeOnTerminate := true;
Устанавливаем приоритет потоков.
ThreadA.Priority := tpIdle;
ThreadB.Priority := tpIdle;
ThreadC.Priority := tpIdle;
Запускаем потоки.
ThreadA.Resume;
ThreadB.Resume;
ThreadC.Resume;