LINUX.ORG.RU

[PyGtk2] Threads, Segmentation Faults


0

0

Добрый вечер.
Кто-нибудь сталкивался с сегфолтами на PyGTK2 при использовании потоков? Основные:
1) Если интенсивно добавлять и удалять строки из treeview из разных потоков, сегфолтится. Мьютексы не спасают, спасают если перед освобождением мьютекса поставить слип на 0.1,0.2 секунды. Проявляется не всегда. Это только у меня так?
2) _Абсолютно рэндомно_ вываливается это:

./main.py:327: PangoWarning: shaping failure, expect ugly output. shape-engine='BasicEngineFc', font='DejaVu Sans 9.9990234375', text=''
gtk.main()
Segmentation fault

на 327 строке gtk.main(). Повторить это вываливание не получается уже неделю. Но вываливается всегда в течение 15 минут, пробовал отключать модули гуйные, думал проблема в коде, но поотключав все по очереди передумал. Что это, и как лечиться?\


Не работать с гуем более, чем из одного потока... совсем... вообще... ну максимум - получить/отправить в другой поток некоторую команду. GTK+ - не многопоточная либа, лучшее, что из нее все-таки можно выжать - глобальную блокировку для проведения операций в другом потоке, но под оффтопом даже это не спасает (в Python, по-видимому, тоже).

ShprotX
()

> Если интенсивно добавлять и удалять строки из treeview из разных потоков, сегфолтится. Мьютексы не спасают, спасают если перед освобождением мьютекса поставить слип на 0.1,0.2 секунды.

Ах да, кажется у меня получилось протелепатировать: мьютекс используется не глобальный (и питон тут не при чем).

ShprotX
()
Ответ на: комментарий от ShprotX

O_O ппц. Спасибо.
Тогда встречный вопрос, тому кто знает, можно ли красиво реализовать блокировку на все операции с гтк? В смысле не перелопачивать всю прогу, и не ловить месяц дедлоки, а как-нибудь так =).

nnkd
() автор топика
Ответ на: комментарий от ShprotX

Да, не глобальный.
просто:

class someclass(..):
def __init__(self, ...):
self._lock = threading.Lock()

...
def somefunc(self, treestore, row):
self._lock.acquire()
treestore.append(row)
#time.sleep(0.1) <--- без этого слипа сегфолтится
self._lock.release()
...

nnkd
() автор топика
Ответ на: комментарий от ShprotX

[форматирование поело]
Да, не глобальный.
просто:

class someclass(..):
    def __init__(self, ...):
        self._lock = threading.Lock()

    ...
    def somefunc(self, treestore, row):
        self._lock.acquire()
        treestore.append(row)
        #time.sleep(0.1) <--- без этого слипа сегфолтится
        self._lock.release()
    ...

nnkd
() автор топика
Ответ на: комментарий от nnkd

time.sleep(0.1) - костыль, позволяющий исключить одновременную работу двух потоков.

Про блокировки тут вроде неплохо написано: http://research.operationaldynamics.com/blogs/andrew/software/gnome-desktop/g.... Ну и официальная дока по gdk_threads_enter/leave.

Смысл в том, что нужна именно глобальная блокировка, поскольку вызовы типа treestore.append(row) делают дофига чего.

ShprotX
()

Спасибо всем.
Сижу ловлю дедлоки >_<.

nnkd
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.