Я определил класс Test
, один из методов которого updater
запускается в отдельном потоке и постоянно обновляет свойство steps
. Я надеюсь на некоторые окончательные советы относительно безопасной модификации собственности и безопасного доступа к собственности в других темах.
Ниже приведен некоторый рабочий код, который отвечает моим требованиям, и широко использует блокировку потока, как предложено здесь . Я развернул блокировку в обоих потоках, а также получил и установил методы, поскольку все операции над свойством steps
не являются атомарными (или, скорее всего, будут в моем законченном коде).
from threading import Thread, Lock
from time import sleep
class Test:
def __init__(self):
self.lock = Lock()
self.steps = 5
self.thread = Thread(target=self.updater)
self.threadRun = True
self.thread.start()
def updater(self):
while self.threadRun:
with self.lock:
self.steps += 1
sleep(0.001)
print('Thread stopped')
def get_steps(self):
with self.lock:
return self.steps
def set_steps(self, steps):
with self.lock:
self.steps = steps
Я понимаю, что непосредственный доступ к свойствам экземпляра предпочтительнее использования методов getter и setter:
a = Test()
steps = a.steps
a.steps = 5
вместо:
a = Test()
steps = a.get_steps()
a.set_steps(5)
но я использовал их здесь, чтобы включить замок. Я не уверен в атомарности прямого доступа к собственности в этом случае, поэтому мог бы избежать блокировки, но кто-то может подтвердить, если это так?
Если я все еще должен использовать блокировку и использовать методы getter и setter для каждого свойства, к которому я хочу получить доступ, как мне развернуть декоратор в классе, чтобы сделать его более умным, когда я масштабируюсь до нескольких свойства? Я ожидаю что-то вроде этого:
from threading import Thread, Lock
from time import sleep
class Test:
def __init__(self):
self.lock = Lock()
self.steps = 5
self.thread = Thread(target=self.updater)
self.threadRun = True
self.thread.start()
def updater(self):
while self.threadRun:
with self.lock:
self.steps += 1
sleep(0.001)
print('Thread stopped')
def locker(self, func):
with self.lock:
return func
@locker
def get_steps(self):
return self.steps
@locker
def set_steps(self, steps):
self.steps = steps
Но в этот момент мои навыки обработки аргументов между классами и декораторами заканчиваются, и я получаю:
TypeError: locker() missing 1 required positional argument: 'func'
Некоторое понимание здесь , но согласно первому комментарию к решению, мне нужно правильно разобраться с аргументами. Я полагаю, что мог бы поместить функцию locker вне класса, но я надеялся поместить ее в класс для аккуратности - я бы не использовал ее в другом месте. Какое здесь элегантное решение?