Ответ 1
Вы можете использовать Locks, RLocks, Semaphores, Conditions, Events и Queues.
И эта статья помогла мне много.
Проверьте это: Блог Laurent Luce
ОК, сначала проверьте следующие коды:
class DemoClass():
def __init__(self):
#### I really want to know if self.Counter is thread-safe.
self.Counter = 0
def Increase(self):
self.Counter = self.Counter + 1
def Decrease(self):
self.Counter = self.Counter - 1
def DoThis(self):
while True:
Do something
if A happens:
self.Increase()
else:
self.Decrease()
time.sleep(randomSecs)
def DoThat(self):
while True:
Do other things
if B happens:
self.Increase()
else:
self.Decrease()
time.sleep(randomSecs)
def ThreadSafeOrNot(self):
InterestingThreadA = threading.Thread(target = self.DoThis, args = ())
InterestingThreadA.start()
InterestingThreadB = threading.Thread(target = self.DoThat, args = ())
InterestingThreadB.start()
Я столкнулся с такой же ситуацией, как и выше. Я действительно хочу знать, является ли это потокобезопасным для self.Counter
, ну, если нет, какие у меня есть варианты? Я могу только думать о threading.RLock()
, чтобы заблокировать этот ресурс, любую лучшую идею?
Вы можете использовать Locks, RLocks, Semaphores, Conditions, Events и Queues.
И эта статья помогла мне много.
Проверьте это: Блог Laurent Luce
Использование поля экземпляра self.Counter
потокобезопасного или "атомарного" . Чтение или назначение одного значения - даже если ему требуется 4 байта в памяти, вы никогда не получите половину измененного значения. Но операция self.Counter = self.Counter + 1
заключается не только в том, что она считывает значение, а затем записывает его - другой поток может изменить значение поля после его чтения и перед его записью.
Итак, вам нужно защитить всю операцию с помощью блокировки.
Так как тело метода - это в основном вся операция, вы можете использовать декоратор для этого. См. Этот ответ для примера: fooobar.com/questions/25284/...
Нет, он не является потокобезопасным - два потока существенно изменяют одну и ту же переменную одновременно. И да, решение является одним из механизмов блокировки в модуле threading
.
BTW, self.Counter
- это переменная экземпляра, а не переменная класса.
self.Counter
является переменной экземпляра, поэтому у каждого потока есть копия.
Если вы объявите переменную вне __init__()
, это будет переменная класса. Все экземпляры класса будут использовать этот экземпляр.