Форум сайта python.su
Всем привет!
Есть гуй на gtk и прокси-сервер. Все в разных потоках. В гуе надо точно знать статус прокси-сервера (работает или нет).
Для этого в классе прокси-сервера предусмотрел переменную _isRunning, которая выставляется при старте внутри сервера в True и соответственно сбрасывается, когда сервер завершает работу. Проблема в том, что этот статус необходимо отслеживать в треде ГУИ. Сейчас для этого применил “события” - то есть прокидываю событие в объект сервера, а там уже при выставлении переменной _isRunning это событие инициализирую (метод set()). Соответственно в гуи я это событие “жду”. Вроде всё стало работать нормально. Вопрос скорее о практике применимости такого подхода в данном случае? Может можно более красиво/правильно это было сделать?
Офлайн
эээ. А в вашем случае события - это что?
Отредактировано (Июль 20, 2010 03:28:11)
Офлайн
Андрей СветловНаверное речь идет о threading.Event, поскольку было упомянуто set(). События используется когда один поток ждет сообщения от другого. Я не думаю что автор блокирует GUI поток и ждет изменения _isRunning… Это было бы нелепо. Я никогда не работал с tkinter (скорее всего на нем пишется), но думаю тут как и везде нужно передавать не event, a сигнал (в случае Qt, или message в случае win32 api). И статус (_isRunning), как параметр. А обработчик этого сигнала в GUI потоке уже пусть делает что хочет. Все это будет thread safe без всяких событий и блокировок. Только нужно знать как этот сигнал передавать чтобы он в GUI потоке обрабатывался. В разных виджетах по разному называется - postmessage, callafter и т.д. просто нужно посмотреть документацию. Канечно можно и не в GUI потоке обрабатывать, если нет нужды что либо отображать.
А в вашем случае события - это что?
Офлайн
nerijusДа, именно о threading.Event. GUI сделал GTK. По поводу того как сделано поясню немного. FooWindow и proxy в разных потокахАндрей СветловНаверное речь идет о threading.Event, поскольку было упомянуто set(). События используется когда один поток ждет сообщения от другого. Я не думаю что автор блокирует GUI поток и ждет изменения _isRunning… Это было бы нелепо. Я никогда не работал с tkinter (скорее всего на нем пишется), но думаю тут как и везде нужно передавать не event, a сигнал (в случае Qt, или message в случае win32 api). И статус (_isRunning), как параметр. А обработчик этого сигнала в GUI потоке уже пусть делает что хочет. Все это будет thread safe без всяких событий и блокировок. Только нужно знать как этот сигнал передавать чтобы он в GUI потоке обрабатывался. В разных виджетах по разному называется - postmessage, callafter и т.д. просто нужно посмотреть документацию. Канечно можно и не в GUI потоке обрабатывать, если нет нужды что либо отображать.
А в вашем случае события - это что?
class FooWindow(object):
def reload(self):
self.proxy = localproxy('127.0.0.1', 8080)
self.proxy.start()
self.status()
def status(self):
print self.proxy.isRunning
class FooWindow(object):
def reload(self):
e = threading.Event()
self.proxy = localproxy('127.0.0.1', 8080, e)
self.proxy.start()
e.wait()
self.status()
def status(self):
print self.proxy.isRunning
Отредактировано (Июль 20, 2010 09:40:45)
Офлайн
Не знаю зачем нужно дождаться установки этого флага… но в принципе если поток стартует быстро и не блокирует GUI, это вполне нормальное решение.
Отредактировано (Июль 20, 2010 10:46:03)
Офлайн
угу. А в общем виде следует строить систему на передаче gtk сигналов.
Офлайн
Спасибо всем ответившим! Кстати, решил таки отказаться от функционала, в котором потребовалось межтредовое взаимодействие. Благо дело это был не ключевой элемент и можно сказать не особо нужный. Но схема с событиями в общем-то отработала неплохо.
Офлайн