Я впервые в процессе конвертации программы из PyGTK в интроспекцию PyGObject, и я попал в блокпост с потоком. У меня есть процесс, который занимает некоторое время, чтобы завершить, поэтому я открываю диалог с индикатором выполнения на нем, и я использую поток для выполнения процесса и для обновления индикатора выполнения. Это отлично работало с PyGTK, но после преобразования в PyGObject я получаю всю обычную неправильную странную странность: программа зависает, но, похоже, висит в разных частях процесса и т.д. Поэтому у меня создается впечатление, что что-то изменилось, но я могу Не поймите, что.
Вот этот простой пример производительности PyGTK: http://aruiz.typepad.com/siliconisland/2006/04/threads_on_pygt.html Как показано на этой странице, код работает. Я преобразовал его в интроспекцию PyGObject, и у меня возникают те же проблемы, что и в моей программе: он зависает, он неправильно обновляет индикатор выполнения и т.д.
import threading
import random, time
from gi.repository import Gtk, Gdk
#Initializing the gtk thread engine
Gdk.threads_init()
class FractionSetter(threading.Thread):
"""This class sets the fraction of the progressbar"""
#Thread event, stops the thread if it is set.
stopthread = threading.Event()
def run(self):
"""Run method, this is the code that runs while thread is alive."""
#Importing the progressbar widget from the global scope
global progressbar
#While the stopthread event isn't setted, the thread keeps going on
while not self.stopthread.isSet() :
# Acquiring the gtk global mutex
Gdk.threads_enter()
#Setting a random value for the fraction
progressbar.set_fraction(random.random())
# Releasing the gtk global mutex
Gdk.threads_leave()
#Delaying 100ms until the next iteration
time.sleep(0.1)
def stop(self):
"""Stop method, sets the event to terminate the thread main loop"""
self.stopthread.set()
def main_quit(obj):
"""main_quit function, it stops the thread and the gtk main loop"""
#Importing the fs object from the global scope
global fs
#Stopping the thread and the gtk main loop
fs.stop()
Gtk.main_quit()
#Gui bootstrap: window and progressbar
window = Gtk.Window()
progressbar = Gtk.ProgressBar()
window.add(progressbar)
window.show_all()
#Connecting the 'destroy' event to the main_quit function
window.connect('destroy', main_quit)
#Creating and starting the thread
fs = FractionSetter()
fs.start()
Gtk.main()
В документации по потоковым функциям Gdk он подчеркивает, что сначала вы должны запустить g_thread_init (NULL) перед запуском gdk_threads_init(). Но чтобы запустить это, вам нужно связать некоторые дополнительные библиотеки. Если я попытаюсь импортировать GLib через интроспекцию, а затем я попытаюсь запустить GLib.thread_init(), я получаю следующую ошибку:
>>> from gi.repository import GLib
>>> GLib.thread_init(None)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/site-packages/gi/types.py", line 44, in function
return info.invoke(*args)
glib.GError: Could not locate g_thread_init: `g_thread_init': /usr/lib/libglib-2.0.so.0: undefined symbol: g_thread_init
Я предполагаю, что это связано с тем, что дополнительные библиотеки потоков не были связаны. Если это причина моих проблем с потоками, как я могу работать с GLib, как если бы эти библиотеки были связаны?