Найти - Пользователи
Полная версия: Без блокировки: сокеты и UI. Возможно?
Начало » Python для экспертов » Без блокировки: сокеты и UI. Возможно?
1 2
rip86oz
Задача - обеспечить параллельную работу программы с сокетами и пользовательским интерфейсом. Т.е. сейчас у меня не получается сделать так, чтобы пользовательский интерфейс не блокировал работу сокетов, с которыми всё нормально. Какие есть варианты для создания UI, не блокируюшего основной цикл программы? Данные из УИ, естественно должны передаваться в основной цикл и наоборот. Подразумевается линукс и венда.
Пробовал - thread, threading, pyGTK. Возможно в pyGTK есть какая-либо функция которая позволяет “опрашивать события” без вызова gtk.main().

Есть мысль про subprocess & communicate(), но как-то неудобно. Да и через PIPE-ы передавать данные не шибко весело.
dimabest
Qt работает с сокетами в неблокирующем режиме.
Посмотрите примеры с классами QTcpServer и QTcpClient для реализации сервера и клиента соответственно.
rip86oz
Поднимаю тему ещё раз:

Вот примерно что нужно:
...
<создание GUI>
...
while True:
...
<проверка возникновения событий GUI без блокировки и их обработка>
...
...
<уничтожение GUI>
...
doza_and
Может вам подойдет концепция Idle? Это обработчик вызываемый когда GUI все переделал. http://www.gtk.org/tutorial1.2/gtk_tut-17.html Но наверное проще отстрелить треды которые будут переводить события из сокетов в GUI events. И ваша схема того что надо странная - сам цикл обработки сообщений не блокируется, это скорее вы его блокируете слушая сокеты. Их можно развести поместив цикл обработки сообщений в свой тред (не main).
rip86oz
Сокеты через селект слушаются. Селект с задеркой 0.01 секунды - небольшая блокировка, чтоб цикл не жрал проц в холостую, но для пользователя не критичная. GUI в проге только как вспомогательная фича, т.к. вместо GUI может быть управление и через терминал, или вообще GUI \ UI не требуется - всё зависит от конфигурации. Привязывать прогу к ГУИ - нет, привязывать ГУИ к проге - ДА. Поэтому использовать функцию основновного цикла обработки событий ГУИ нельзя вообще никак. Нужна функция именно проверки возникновения событий ГУИ.
С тредами - запарка, т.к. GIL реальных тредов не даёт.
Думаю только насчёт subprocess - реальная параллельная работа. А процессы через опять-же сокеты связать. Геморно - но других выходов нет пока что.
doza_and
С subprocess будет гемор с передачей данных (они реально в другом процессе). Треды питоновские конечно сильно потеряли привлекательности от GIL, но в вашем случае основное ожидание будет в операционке поэтому GIL почти не будет мешать. Я думаю в вашем случае лучше всего пустить app.mainloop в параллельном треде а из основного треда уведомлять GUI о возникших событиях и в обратную сторону тоже уведомления слать.

rip86oz
GIL реальных тредов не даёт
Я думаю это заблуждение - треды самые настоящие, Просто часто синхронизируются - по атомарным командам интерпретатора. Может более знающие люди меня поправят.
rip86oz
Я уже пускал два треда - один с GTK-ым main-ом, второй - свои циклом… что-ж. GTK победил, заблокировав выполнение второго треда.)

С subprocess-ом дело понятное - что в разных процах данные. Но так это не беда - просто трата ресурсов компа на передачу инфы)). От гуи идёт только управление, основная работа и все данные - в другом процессе.
doza_and
1 Будет неплохо посмотреть ваш код
2 как с любыми тредами помоему - надо инициировать процесс переключения. В mainloop на обработку idle можно вставить sleep(0). Это сделает переключения тредов более частым процессом.
rip86oz
def recurs_mod_loop(pi,i) :
global ilist
global olist
global xdict
global cvars

node = conn_pipes[pi][i]

if not node.inited :
node.init()

if node.inited :
if node.workloop_in() >= 0 :
if i < max_conn_pipes[pi] :
recurs_mod_loop(pi,i+1)
if node.workloop_out() < 0 :
for j in range(0,max_conn_pipes[pi]+1-i) :
rev_conn_pipes[pi][j].close()
else :
for j in range(0,max_conn_pipes[pi]+1-i) :
rev_conn_pipes[pi][j].close()
...
while True :
...
pi = 0
while pi < len(conn_pipes):
...
recurs_mod_loop(pi,0)
...
pi += 1
...
node - есть по сути ячейка программы отвечающая за приём\передачу\обработку данных. ГУИ, сокеты и т.п. могут быть в любых node-ах. Т.е. если где-то node “встревает”, то прога стопорится. Я понимаю, что лучше делать это всё с нормальными тредами на нормальном языке, но надо сделать именно на питоне.
doza_and
Ваш код нельзя запустить - поэтому не очень понятно в чем проблема. Не моглибы вы его упростить
def RunGui():
.....
thread_gui=threading.Thread(target=RunGui)
thread_gui.start()
while 1:
myactions()
ну както так как я написал - чтобы можно было запустить и увидеть проблему.
Стопарение проги хорошо имитируется методом input
А по поводу -нормальных тредов и языка думаю вы не правы - во всех языках есть трудности :)
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB