Форум сайта python.su
Добрый день!
Поясните, правильно ли я использую блокировку (Lock()) в следующем коде или она не требуется:
import threading
class _ServerThread(threading.Thread):
_lock = None
_daemon = None
def __init__(self):
threading.Thread.__init__(self)
self._lock = threading.Lock()
def run(self):
self._lock.acquire()
self._daemon=Daemon()
self._lock.release()
self._daemon.requestLoop() # Бесконечный цикл внутри
def stop(self):
self._lock.acquire()
self._daemon.shutdown()
self._lock.release()
Офлайн
В run не нужен. А в stop, смотря что происходит в shutdown. Но скорее всего тоже не нужен (главное что бы stop вызывался один раз).
Офлайн
Спасибо!
Не совсем понято только, причем здесь количество вызовов? Меня интересует блокировка как защита от одновременного обращения из разных потоков.
Офлайн
К чему - обращения? Какой объект вы защищаете?
Офлайн
AlexandrRВ этом то и дело, что если архитектура кривая, этот stop может быть вызван с двух разных потоков одновременно.
Спасибо!
Не совсем понято только, причем здесь количество вызовов? Меня интересует блокировка как защита от одновременного обращения из разных потоков.
Офлайн
Андрей СветловЗащищаю _daemon. Во всяком случае я пытаюсь это сделать, но может этого не нужно делать? Вот это и пытаюсь спросить.
К чему - обращения? Какой объект вы защищаете?
nerijusТак дело не в “кривой” архитектуре - это сервер, то есть запросы с клиентов идут асинхронно и независимо. Но можно допустить, что stop() будет вызван ровно 1 раз. Но может случиться так, что вызван он будет ровно в тот момент, когда выполнение метода run() в самом начале и тогда _daemon одновременно попытаются изменить два потока. А это же вроде не есть гут?
В этом то и дело, что если архитектура кривая, этот stop может быть вызван с двух разных потоков одновременно.
Офлайн
Создавайте Daemon в конструкторе.
th = _ServerThread()
th.start()
th.stop()
import threading
class _ServerThread(threading.Thread):
_lock = None
_daemon = None
def __init__(self):
threading.Thread.__init__(self)
self._lock = threading.Lock()
self._condition = threading.Condition(self._lock)
self._started = False
self._stopping = False
def run(self):
try:
self._condition.acquire()
self._daemon=Daemon()
self._started = True
self._condition.notifyAll()
finally:
self._condition.release()
self._daemon.requestLoop() # Бесконечный цикл внутри
def stop(self):
try:
self._condition.acquire()
while not self._started:
self._condition.wait()
if not self._stopping:
self._daemon.shutdown()
self._stopping = True
finally:
self._condition.release()
Офлайн
Андрей, спасибо!
Очень грамотный и обстоятельный ответ. И как раз именно то, что мне нужно. Все-таки 5 звезд в профиле неспроста.
P.S. Про заворачивание блокировок в try/finally я как-то забыл.
Офлайн