Написать класс Lock, который реализует абстракцию «двоичный семафор», а также декоратор класса @Lock.locked, который добавляет поле-семафор .lock в класс. Протокол работы семафора:
obj.lock = "имя" — задаём имя семафора, который собираемся захватывать
- Если при этом какой-то семафор был уже захвачен (в том числе с тем же именем), он освобождается
obj.lock — атомарная операция проверки доступности и одновременного захвата семафора. Совпадает с именем семафора, если его захватить удалось, если нет — равна None.
Если семафор уже захвачен именно этим lock-ом, результат — имя семафора
Если семафор не задан, результат — None
del obj.lock — освобождение семафора, если он захвачен именно этим lock-ом
- В противном случае не происходит ничего
При удалении объекта, содержащего lock (например, в результате уменьшения счётчика ссылок до 0), захваченный семафор необходимо освободить.
1 @Lock.locked
2 class A(str):
3 pass
4
5
6 a, b = A("a"), A("b")
7 a.lock = "S" # Регистрация на семафор S
8 b.lock = "S" # Регистрация на семафор S
9 print(a, a.lock) # Успешный захват семафора S
10 print(a, a.lock) # Семафор S уже захвачен нами
11 print(b, b.lock) # Неуспешный захват семафора S
12 del a.lock # Освобождение семафора S
13 print(b, b.lock) # Успешный захват семафора S
14 b.lock = "T" # Регистрация на семафор T, освобождает предыдущий семафор
15 print(b, b.lock) # Успешный захват семафора T
16 del b # Удаление объекта-носителя освобождает семафор
17 a.lock = "T" # Регистрация на семафор T, освобождает предыдущий семафор
18 print(a, a.lock) # Успешный захват семафора T
Это задача на:
- декоратор класса
дескриптор (очевидно, lock)
использование метода .__del__() — он понадобится для последнего условия
там же надо озаботиться вызовом .__del__(), если он есть у родительского класса (вернее, super-а)
a S a S b None b S b T a T