Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Лабораторные / ОС_лабораторная 3

.docx
Скачиваний:
4
Добавлен:
12.02.2024
Размер:
639.46 Кб
Скачать

МИНИСТЕРСТВО ЦИФРОВОГО РАЗВИТИЯ, СВЯЗИ И МАССОВЫХ КОММУНИКАЦИЙ РОССИЙСКОЙ ФЕДЕРАЦИИ

Ордена Трудового Красного Знамени федеральное государственное бюджетное образовательное учреждение высшего образования

«Московский технический университет связи и информатики»

Кафедра «Системного программирования»

Дисциплина «Операционные системы»

Лабораторная работа 3

«Средства синхронизации в ОС GNU/LINUX»

Выполнил:

студент группы БСТ2104

Станишевский И.А.

Проверила: Алексанян Д. А.

Москва, 2023 г.

Содержание

Цель работы 3

Задания на лабораторную работу 3

Решение задач 4

Задание с барьером 4

Задача с сигналами 6

Задача с мьютексами 9

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

Вывод 14

Цель работы 3

Задания на лабораторную работу 3

Решение задач 4

Задача с мьютексами 4

Задание с барьером 6

Задача с сигналами 9

Вывод 12

  1. Цель работы

Получить практические навыки по использованию синхронизации потоков.

  1. Задания на лабораторную работу

  1. Изучить теоретическую часть лабораторной работы.

  2. Исследовать на конкретном примере особенности 3 по выбору из указанных методов синхронизации потоков:

1) семафоры

2) сигналы

3) мьютексы

4) барьеры

Задачи для синхронизации выбрать, исходя из особенностей методов, на свое усмотрение.

  1. Решение задач

    1. Задание с барьером

В магазине работает несколько курьеров, которые доставляют товары. Необходимо синхронизировать их работу таким образом, чтобы все курьеры одновременно завершили работу свою.

Когда каждый курьер завершает доставку (courier_work), он вызывает barrier.wait(), который останавливает выполнение этого потока до тех пор, пока остальные курьеры не достигнут той же точки. Только когда все 4 курьера достигнут барьера, они смогут завершить выполнение. Барьер специально предназначен для точки синхронизации нескольких потоков и обеспечения их одновременного продолжения.

Решение задачи представлено на скриншоте 3:

Рисунок 3 — Код программы

Текст программы:

import threading

import time

barrier = threading.Barrier(4) # инициализация барьера с ожиданием 4 курьеров

def courier_work(courier_id):

print(f"Курьер {courier_id} начинает доставку")

time.sleep(3) # имитация доставки товара

print(f"Курьер {courier_id} завершил доставку и ждет остальных")

barrier.wait() # ожидание всех курьеров

# создание и запуск потоков для курьеров

couriers = [threading.Thread(target=courier_work, args=(i,)) for i in range(1, 5)]

for courier in couriers:

courier.start()

# ожидание завершения работы всех курьеров

for courier in couriers:

courier.join()

print("Все курьеры завершили доставку")

Рисунок 4 — результат работы программы

    1. Задача с сигналами

После долгого рабочего дня специалист по операционным системам возвращается домой. Домой он едет на своей машине. На дороге водитель должен соблюдать правила дорожного движения. Он подъезжает к светофору и ждет, когда загорится зеленый свет, чтобы продолжить путь домой.

Нужно написать программу, в которой будет два потока. Водитель будет ожидать сигнала от светофора и продолжать ехать на машине, если сигнал получен.

Решение задачи представлено на скриншоте 5:

Рисунок 5 — код программы

Текст программы:

import threading

import time

signal = threading.Event() # создание объекта сигнала

# движение машины

def car_driver():

print("Водитель подъезжает к светофору и ждет зеленый свет")

signal.wait() # ожидание сигнала от светофора

print("Водитель видит зеленый свет и продолжает свой путь")

# работа светофора

def traffic_light():

print("Красный свет! Запрещено ехать!")

time.sleep(5) # имитация ожидания на светофоре

print("Желтый свет! Водитель должен приготовиться!")

time.sleep(5) # имитация ожидания на светофоре

print("Зеленый свет! Сигнал для движения")

signal.set() # установка сигнала для продолжения движения

# создание потоков

car_thread = threading.Thread(target=car_driver)

traffic_light_thread = threading.Thread(target=traffic_light)

# Запускаем потоки

car_thread.start()

traffic_light_thread.start()

# Ждем завершения обоих потоков

car_thread.join()

traffic_light_thread.join()

Рисунок 6 — результат работы программы

    1. Задача с мьютексами

Пускай есть два бизнесмена, которые работают с одним банковским счётом. В определенный момент совершать операции с банковским счетом может только один бизнесмен. Каждый из них выполняет какую-то одну работу: либо пополняет счет, либо проверяет баланс счета.

Решение задачи представлено на скриншоте 1:

Рисунок 1 — Код программы

Текст программы:

import threading

import time

lock = threading.Lock() # Создаем объект мьютекса

account_balance = [1000] # Используем список для хранения баланса

print(f"Начальный баланс: {account_balance[0]} единиц")

time.sleep(2)

# пополнение баланса

def businessman1_deposit_money(account_balance, amount):

lock.acquire() # Захватываем мьютекс перед обращением к общему ресурсу

account_balance[0] += amount

print(f"Бизнесмен 1 решает пополнить баланс на {amount} единиц.")

print(f"Бизнесмен 1 решает завершает работу с банковским счетом")

lock.release() # Освобождаем мьютекс после завершения работы

# проверка баланса

def businessman2_check_balance(account_balance):

lock.acquire() # Захватываем мьютекс перед обращением к общему ресурсу

time.sleep(2)

print("Бизнесмен 2 решает проверить баланс")

time.sleep(2)

print(f"Текущий баланс: {account_balance[0]} единиц")

print(f"Бизнесмен 2 решает завершает работу с банковским счетом")

lock.release() # Освобождаем мьютекс после завершения работы

# Создаем потоки

businessman1_thread = threading.Thread(target=businessman1_deposit_money, args=(account_balance, 1500))

businessman2_thread = threading.Thread(target=businessman2_check_balance, args=(account_balance,))

# Запускаем потоки

businessman1_thread.start()

businessman2_thread.start()

# Ждем завершения обоих потоков

businessman1_thread.join()

businessman2_thread.join()

print("Сеанс работы с банковским счётом завершен")

Рисунок 2 — результат работы программы

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

Синхронизация поток разных процессов

Рисунок 7 – запуск кода

Рисунок 8 – Вывод кода

  1. Вывод

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