Лабораторные / ОС_лабораторная 3
.docxМИНИСТЕРСТВО ЦИФРОВОГО РАЗВИТИЯ, СВЯЗИ И МАССОВЫХ КОММУНИКАЦИЙ РОССИЙСКОЙ ФЕДЕРАЦИИ
Ордена Трудового Красного Знамени федеральное государственное бюджетное образовательное учреждение высшего образования
«Московский технический университет связи и информатики»
Кафедра «Системного программирования»
Дисциплина «Операционные системы»
Лабораторная работа 3
«Средства синхронизации в ОС GNU/LINUX»
Выполнил:
студент группы БСТ2104
Станишевский И.А.
Проверила: Алексанян Д. А.
Москва, 2023 г.
Содержание
Цель работы 3
Задания на лабораторную работу 3
Решение задач 4
Задание с барьером 4
Задача с сигналами 6
Задача с мьютексами 9
Мьютекс обеспечивает эксклюзивный доступ к общему ресурсу (в данном случае банковскому счету). Когда один из бизнесменов начинает выполнять операцию, он захватывает мьютекс, чтобы другой бизнесмен не мог одновременно обращаться к счету и изменять его состояние. Когда первый бизнесмен закончил операцию, он освобождает мьютекс для доступа другого бизнесмена. 11
Вывод 14
Цель работы 3
Задания на лабораторную работу 3
Решение задач 4
Задача с мьютексами 4
Задание с барьером 6
Задача с сигналами 9
Вывод 12
Цель работы
Получить практические навыки по использованию синхронизации потоков.
Задания на лабораторную работу
Изучить теоретическую часть лабораторной работы.
Исследовать на конкретном примере особенности 3 по выбору из указанных методов синхронизации потоков:
1) семафоры
2) сигналы
3) мьютексы
4) барьеры
Задачи для синхронизации выбрать, исходя из особенностей методов, на свое усмотрение.
Решение задач
Задание с барьером
В магазине работает несколько курьеров, которые доставляют товары. Необходимо синхронизировать их работу таким образом, чтобы все курьеры одновременно завершили работу свою.
Когда каждый курьер завершает доставку (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 — результат работы программы
Задача с сигналами
После долгого рабочего дня специалист по операционным системам возвращается домой. Домой он едет на своей машине. На дороге водитель должен соблюдать правила дорожного движения. Он подъезжает к светофору и ждет, когда загорится зеленый свет, чтобы продолжить путь домой.
Нужно написать программу, в которой будет два потока. Водитель будет ожидать сигнала от светофора и продолжать ехать на машине, если сигнал получен.
Решение задачи представлено на скриншоте 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 — Код программы
Текст программы:
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 — результат работы программы
Мьютекс обеспечивает эксклюзивный доступ к общему ресурсу (в данном случае банковскому счету). Когда один из бизнесменов начинает выполнять операцию, он захватывает мьютекс, чтобы другой бизнесмен не мог одновременно обращаться к счету и изменять его состояние. Когда первый бизнесмен закончил операцию, он освобождает мьютекс для доступа другого бизнесмена.
Синхронизация поток разных процессов
Рисунок 7 – запуск кода
Рисунок 8 – Вывод кода
Вывод
В ходе работы я изучил основные механизмы синхронизации, которые помогают взаимодействовать с потоками.