Уведомления

Группа в Telegram: @pythonsu

#1 Июль 20, 2010 00:01:56

pento
От:
Зарегистрирован: 2007-05-29
Сообщения: 100
Репутация: +  0  -
Профиль   Отправить e-mail  

Многопоточность, события

Всем привет!

Есть гуй на gtk и прокси-сервер. Все в разных потоках. В гуе надо точно знать статус прокси-сервера (работает или нет).
Для этого в классе прокси-сервера предусмотрел переменную _isRunning, которая выставляется при старте внутри сервера в True и соответственно сбрасывается, когда сервер завершает работу. Проблема в том, что этот статус необходимо отслеживать в треде ГУИ. Сейчас для этого применил “события” - то есть прокидываю событие в объект сервера, а там уже при выставлении переменной _isRunning это событие инициализирую (метод set()). Соответственно в гуи я это событие “жду”. Вроде всё стало работать нормально. Вопрос скорее о практике применимости такого подхода в данном случае? Может можно более красиво/правильно это было сделать?



Офлайн

#2 Июль 20, 2010 03:27:44

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

Многопоточность, события

эээ. А в вашем случае события - это что?



Отредактировано (Июль 20, 2010 03:28:11)

Офлайн

#3 Июль 20, 2010 04:21:54

nerijus
От:
Зарегистрирован: 2010-06-03
Сообщения: 93
Репутация: +  1  -
Профиль   Отправить e-mail  

Многопоточность, события

Андрей Светлов
А в вашем случае события - это что?
Наверное речь идет о threading.Event, поскольку было упомянуто set(). События используется когда один поток ждет сообщения от другого. Я не думаю что автор блокирует GUI поток и ждет изменения _isRunning… Это было бы нелепо. Я никогда не работал с tkinter (скорее всего на нем пишется), но думаю тут как и везде нужно передавать не event, a сигнал (в случае Qt, или message в случае win32 api). И статус (_isRunning), как параметр. А обработчик этого сигнала в GUI потоке уже пусть делает что хочет. Все это будет thread safe без всяких событий и блокировок. Только нужно знать как этот сигнал передавать чтобы он в GUI потоке обрабатывался. В разных виджетах по разному называется - postmessage, callafter и т.д. просто нужно посмотреть документацию. Канечно можно и не в GUI потоке обрабатывать, если нет нужды что либо отображать.



Офлайн

#4 Июль 20, 2010 09:38:23

pento
От:
Зарегистрирован: 2007-05-29
Сообщения: 100
Репутация: +  0  -
Профиль   Отправить e-mail  

Многопоточность, события

nerijus
Андрей Светлов
А в вашем случае события - это что?
Наверное речь идет о threading.Event, поскольку было упомянуто set(). События используется когда один поток ждет сообщения от другого. Я не думаю что автор блокирует GUI поток и ждет изменения _isRunning… Это было бы нелепо. Я никогда не работал с tkinter (скорее всего на нем пишется), но думаю тут как и везде нужно передавать не event, a сигнал (в случае Qt, или message в случае win32 api). И статус (_isRunning), как параметр. А обработчик этого сигнала в GUI потоке уже пусть делает что хочет. Все это будет thread safe без всяких событий и блокировок. Только нужно знать как этот сигнал передавать чтобы он в GUI потоке обрабатывался. В разных виджетах по разному называется - postmessage, callafter и т.д. просто нужно посмотреть документацию. Канечно можно и не в GUI потоке обрабатывать, если нет нужды что либо отображать.
Да, именно о threading.Event. GUI сделал GTK. По поводу того как сделано поясню немного. FooWindow и proxy в разных потоках
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
isRunning устанавливается в True в методе start() прокси. Но при вызове status() оно ещё False. Сейчас я по сути протаскиваю объект “события” в объект прокси, там его при старте (сразу после выставления переменной isRunning) выставляю методом set(), и код преобритает вид примерно такого:
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)

Офлайн

#5 Июль 20, 2010 10:42:23

nerijus
От:
Зарегистрирован: 2010-06-03
Сообщения: 93
Репутация: +  1  -
Профиль   Отправить e-mail  

Многопоточность, события

Не знаю зачем нужно дождаться установки этого флага… но в принципе если поток стартует быстро и не блокирует GUI, это вполне нормальное решение.



Отредактировано (Июль 20, 2010 10:46:03)

Офлайн

#6 Июль 20, 2010 15:08:56

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

Многопоточность, события

угу. А в общем виде следует строить систему на передаче gtk сигналов.



Офлайн

#7 Июль 28, 2010 22:00:54

pento
От:
Зарегистрирован: 2007-05-29
Сообщения: 100
Репутация: +  0  -
Профиль   Отправить e-mail  

Многопоточность, события

Спасибо всем ответившим! Кстати, решил таки отказаться от функционала, в котором потребовалось межтредовое взаимодействие. Благо дело это был не ключевой элемент и можно сказать не особо нужный. Но схема с событиями в общем-то отработала неплохо.



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version