diff --git a/module10/hw3/deposit.png b/module10/hw3/deposit.png new file mode 100644 index 0000000..3f7efb5 Binary files /dev/null and b/module10/hw3/deposit.png differ diff --git a/module10/hw3/module_10_3.py b/module10/hw3/module_10_3.py new file mode 100644 index 0000000..2ce7769 --- /dev/null +++ b/module10/hw3/module_10_3.py @@ -0,0 +1,101 @@ +# Домашнее задание по теме "Блокировки и обработка ошибок" +""" +Задача "Банковские операции": +Необходимо создать класс Bank со следующими свойствами: + +Атрибуты объекта: + * balance - баланс банка (int) + * lock - объект класса Lock для блокировки потоков. + +Методы объекта: + +Метод deposit: + 1. Будет совершать 100 транзакций пополнения средств. + 2. Пополнение - это увеличение баланса на случайное целое число от 50 до 500. + 3. Если баланс больше или равен 500 и замок lock заблокирован - lock.locked(), + то разблокировать его методом release. + 4. После увеличения баланса должна выводится строка "Пополнение: <случайное число>. Баланс: <текущий баланс>". + 5. Также после всех операций поставьте ожидание в 0.001 секунды, тем самым имитируя скорость выполнения пополнения. + +Метод take: + 1. Будет совершать 100 транзакций снятия. + 2. Снятие - это уменьшение баланса на случайное целое число от 50 до 500. + 3. В начале должно выводится сообщение "Запрос на <случайное число>". + 4. Далее производится проверка: если случайное число меньше или равно текущему балансу, то произвести снятие, + уменьшив balance на соответствующее число и вывести на экран + "Снятие: <случайное число>. Баланс: <текущий баланс>". + 5. Если случайное число оказалось больше баланса, то вывести строку "Запрос отклонён, недостаточно средств" + и заблокировать поток методом acquire. + +Далее создайте объект класса Bank и создайте 2 потока для его методов deposit и take. +Запустите эти потоки. +После конца работы потоков выведите строку: "Итоговый баланс: <баланс объекта Bank>". + +По итогу вы получите скрипт разблокирующий поток до баланса равному 500 и больше или блокирующий, +когда происходит попытка снятия при недостаточном балансе. +""" +import threading +import random +import time + + +class Bank: + def __init__(self, initial_balance: int = 0): + self.balance = initial_balance + self.lock = threading.Lock() + + + def deposit(self): + """ + Метод пополнения баланса + """ + with self.lock: + for _ in range(100): + # случайная сумма пополнения от 50 до 500 + amount = random.randint(50, 500) + # пополнение баланса + self.balance += amount + print(f"Пополнение: {amount}. Баланс: {self.balance}") + # если баланс >= 500 и замок заблокирован, то разблокируем его + if self.balance >= 500 and self.lock.locked(): + self.lock.release() + # задержка для имитации времени выполнения + time.sleep(0.001) + + + def take(self): + """ + Метод снятия средств + """ + with self.lock: + for _ in range(100): + # случайная сумма снятия от 50 до 500 + amount = random.randint(50, 500) + print(f"Запрос на {amount}") + if amount <= self.balance: + # снятие средств + self.balance -= amount + print(f"Снятие: {amount}. Баланс: {self.balance}") + else: + # Запрос отклонен из-за недостатка средств + print("Запрос отклонен, недостаточно средств") + # блокируем поток для ожидания пополнения + self.lock.acquire() + # задержка для имитации времени выполнения + time.sleep(0.001) + + +# пример использования +bk = Bank() + +# Т.к. методы принимают self, в потоки нужно передать сам объект класса Bank +th1 = threading.Thread(target=Bank.deposit, args=(bk,)) +th2 = threading.Thread(target=Bank.take, args=(bk,)) + +th1.start() +th2.start() +th1.join() +th2.join() + +print(f'Итоговый баланс: {bk.balance}') + diff --git a/module10/hw3/request.png b/module10/hw3/request.png new file mode 100644 index 0000000..501659b Binary files /dev/null and b/module10/hw3/request.png differ diff --git a/module10/hw3/take.png b/module10/hw3/take.png new file mode 100644 index 0000000..1515fe1 Binary files /dev/null and b/module10/hw3/take.png differ