потоки в питоне (и глюки gtk)

Модератор: Модераторы разделов

Аватара пользователя
nadge
Сообщения: 1519
ОС: ArchLinux, Ubuntu 10.10

потоки в питоне

Сообщение nadge »

Имеется код:

Код: Выделить всё

import threading, gtk
from time import sleep

def updaterloop():
    while True:
        print "something"
        sleep(1)

uloop = threading.Thread(target=updaterloop)
uloop.start()
gtk.main()


Работает это так:
1. Запускается дочерний поток, успевает один раз выполниться цикл (появляется надпись).
2. Дальше оба потока (основной и дочерний) ждут завершения gtk.main. Самое главное - тормозится дочерний, хотя и не должен.
3. Дальше цикл в дочернем продолжается, программу приходится убивать из консоли.

Должно быть:
1. Запускается дочерний поток и спокойно себе работает параллельно. Он никого не трогает и, что важнее, его никто не трогает.
2. Запускается и работает gtk.main в основном потоке. Параллельно с дочерним потоком, не вмешиваясь в работу последнего.
3. После завершения gtk.main завершается ВСЯ программа, включая дочерние потоки.

Если заменить gtk.main на sleep, то все работает как надо.

Пункт 3 вобщем-то не обязательно, но желательно.


Вопросы:
1. Как это сделать?
2. В чем причина такого поведения?
3. За счет чего (каких функций) gtk тормозит другой поток? Я тоже так хочу уметь :)
4. Как полностью завершить программу, т.е. вместе с остальными потоками? Т.е. чтобы после выхода из gtk.main программа завершалась, а не продолжалось выполнение дочернего потока.


З.Ы. Чую одной из частей моего тела - надо было выбрать Qt :)
Спасибо сказали:
Аватара пользователя
RasenHerz
Сообщения: 1341
ОС: Arch Linux amd64

Re: потоки в питоне

Сообщение RasenHerz »

Скорее всего gtk.main не находит виджетов для отображения и просто выходит.

P.S. http://bugs.python.org/issue6073 - вдруг поможет..
Спасибо сказали:
Аватара пользователя
nadge
Сообщения: 1519
ОС: ArchLinux, Ubuntu 10.10

Re: потоки в питоне

Сообщение nadge »

Это я тут сократил код для наглядности. Глюк есть как тут, так и в оригинальной прогамме (ради которой, собственно, я и создал тему). В оригинальной программе виджеты есть и gtk.main их корректно обрабатывает. Т.е. это похоже не влияет.


А вот за ссылку спасибо. Вставка gobject.threads_init() похоже решает проблему. (Ну блин, я весь мануал по python и pygtk перерыл, этого не нашел.)


Остается вопрос: как полностью завершить программу, вместе с остальными потоками? Т.е. чтобы после выхода из gtk.main программа завершалась, а не продолжалось выполнение дочернего потока?
Спасибо сказали:
Аватара пользователя
Portnov
Модератор
Сообщения: 1786
Статус: Матёрый линуксоид
ОС: Debian testing/unstable

Re: потоки в питоне

Сообщение Portnov »

gtk.gdk.threads_init()
Работа: Ubuntu 9.10
Дом: Debian testing/unstable и на всякий случай winxp в virtualbox.
Для разнообразия: моя домашняя страница -http://iportnov.ru
Спасибо сказали:
Аватара пользователя
RasenHerz
Сообщения: 1341
ОС: Arch Linux amd64

Re: потоки в питоне

Сообщение RasenHerz »

nadge писал(а):
26.12.2009 22:56
Остается вопрос: как полностью завершить программу, вместе с остальными потоками? Т.е. чтобы после выхода из gtk.main программа завершалась, а не продолжалось выполнение дочернего потока?

вызов exit(0) сразу после gtk.main не работает?
Спасибо сказали:
Аватара пользователя
nadge
Сообщения: 1519
ОС: ArchLinux, Ubuntu 10.10

Re: потоки в питоне

Сообщение nadge »

RasenHerz
Мне это почему-то не пришло в голову :)


З.Ы. Спасибо всем за ответы. Проблема решена.
Спасибо сказали:
d_n_k
Сообщения: 636
ОС: Gentoo GNU/Linux

Re: потоки в питоне

Сообщение d_n_k »

1. Как это сделать?

никак так работает python.
в python'е нет потоков, какие бы обертки вокруг реальных потоков не изобретались. а все из-за GIL (Global Interpretator Lock)
в Qt такое же поведение.
2. В чем причина такого поведения?

причина в реализации python'а, во всех реализациях присутствует GIL. он нужен для защиты данных интерпретатора.
интерпретатор блокируется при выполнении очередной инструкции потока и каждые N инструкции блокировка снимается и управление передается ждущим потокам.

3. За счет чего (каких функций) gtk тормозит другой поток? Я тоже так хочу уметь

не знаю как точно реализован в pygtk вызов gtk.main(), но скорее всего там стоит вызов функции gtk_main(). но этам фукнции не возвращает управление до выхода из основного цикла.
те получается что интерпретатор заблокирован для выхода из основного цикла. что приводит к "заморозке" всех python-потоков

4. Как полностью завершить программу, т.е. вместе с остальными потоками? Т.е. чтобы после выхода из gtk.main программа завершалась, а не продолжалось выполнение дочернего потока.

python-программа выполняется до тех пор пока выполняется хотя бы 1 python-поток
если вам нужно чтобы поток не блокировал выход, то сделается его демоном (свойство daemon=True)


зы: почитайте про GIL
все сказанное есть имхо...
Спасибо сказали:
Аватара пользователя
nadge
Сообщения: 1519
ОС: ArchLinux, Ubuntu 10.10

Re: потоки в питоне

Сообщение nadge »

d_n_k
Списибо за разъяснения. Про GIL почитал. По вопросу, который я изначально задал, все же несколько помогает вызов gtk.gdk.threads_init() (это нужно, чтобы интерфейс GTK не застывал).

А в общем виде, получается, надо использовать вместо потоков отдельные процессы и синхронизировать их, так?
Спасибо сказали:
Аватара пользователя
Portnov
Модератор
Сообщения: 1786
Статус: Матёрый линуксоид
ОС: Debian testing/unstable

Re: потоки в питоне

Сообщение Portnov »

nadge писал(а):
05.01.2010 19:46
А в общем виде, получается, надо использовать вместо потоков отдельные процессы и синхронизировать их, так?

Да. Более того, в большинстве случаев это разумно и вне питона.
Работа: Ubuntu 9.10
Дом: Debian testing/unstable и на всякий случай winxp в virtualbox.
Для разнообразия: моя домашняя страница -http://iportnov.ru
Спасибо сказали:
Аватара пользователя
nadge
Сообщения: 1519
ОС: ArchLinux, Ubuntu 10.10

Re: потоки в питоне

Сообщение nadge »

Спасибо. Решил так и делать.
Спасибо сказали: