Форум сайта python.su
0
Добрый день!
Поясните, правильно ли я использую блокировку (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()
Офлайн
1
В run не нужен. А в stop, смотря что происходит в shutdown. Но скорее всего тоже не нужен (главное что бы stop вызывался один раз).
Офлайн
0
Спасибо!
Не совсем понято только, причем здесь количество вызовов? Меня интересует блокировка как защита от одновременного обращения из разных потоков.
Офлайн
14
К чему - обращения? Какой объект вы защищаете?
Офлайн
1
AlexandrRВ этом то и дело, что если архитектура кривая, этот stop может быть вызван с двух разных потоков одновременно.
Спасибо!
Не совсем понято только, причем здесь количество вызовов? Меня интересует блокировка как защита от одновременного обращения из разных потоков.
Офлайн
0
Андрей СветловЗащищаю _daemon. Во всяком случае я пытаюсь это сделать, но может этого не нужно делать? Вот это и пытаюсь спросить.
К чему - обращения? Какой объект вы защищаете?
nerijusТак дело не в “кривой” архитектуре - это сервер, то есть запросы с клиентов идут асинхронно и независимо. Но можно допустить, что stop() будет вызван ровно 1 раз. Но может случиться так, что вызван он будет ровно в тот момент, когда выполнение метода run() в самом начале и тогда _daemon одновременно попытаются изменить два потока. А это же вроде не есть гут?
В этом то и дело, что если архитектура кривая, этот stop может быть вызван с двух разных потоков одновременно.
Офлайн
14
Создавайте 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()
Офлайн
0
Андрей, спасибо!
Очень грамотный и обстоятельный ответ. И как раз именно то, что мне нужно. Все-таки 5 звезд в профиле неспроста.
P.S. Про заворачивание блокировок в try/finally я как-то забыл.
Офлайн