Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added module10/hw3/deposit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
101 changes: 101 additions & 0 deletions module10/hw3/module_10_3.py
Original file line number Diff line number Diff line change
@@ -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}')

Binary file added module10/hw3/request.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added module10/hw3/take.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.