Единственная известная мне политика заключается в том, что только один поток может обращаться к библиотекам GTK в любое время.
Если вы хотите, чтобы графический интерфейс выполнялся в своем собственном вторичном потоке, вы должны быть уверены, что это единственный поток, обращающийся к GTK, поскольку GTK не является поточно-ориентированным.Вот почему в ваших вторичных случаях он работает только тогда, когда GTK импортируется из потока.Если он загружен вне потока, то технически основной поток также использует его в некоторой степени, и оба потока могут одновременно пытаться получить доступ к библиотеке. Причина, по которой ваши первичные сценарии работают, заключается в том, что вы правильно блокируете доступ кбиблиотеки GTK с gtk.gdk.threads_enter () и threads_leave ().Я думаю, что вы могли бы избавиться от них в файле secondthread_gtkgdk_import.py, и это сработает, поскольку есть только один поток, который знает о загрузке GTK.
Теперь это предположение с моей стороны, поскольку я незнаю много об AT-SPI.Так как вы уже вызываете условия гонки из двух ваших отдельных потоков в файлах virtualthread_gobject.py и secondthread_gtkgdk.py, AT-SPI также может каким-то образом зависеть от этого состояния.
Если вы действительно хотите, чтобы ваш GUI был во вторичном потоке, используйте файлthirthread_gtkgdk_import.py (возможно, удалив threads_enter () и threads_leave () как ненужные).Вместо этого я бы рекомендовал использовать графический интерфейс в качестве основного потока и запускать все фоновые процессы в дочерних потоках.
Сравните следующие два примера:
import threading
import time
class mythread(threading.Thread):
def __init__(self):
super(mythread, self).__init__()
def run(self):
print time.ctime()
t = mythread()
t.run()
print time.ctime()
$ python2 test.py
Mon Aug 15 23:12:41 2011
Mon Aug 15 23:12:41 2011
import threading
class mythread(threading.Thread):
def __init__(self):
super(mythread, self).__init__()
def run(self):
import time
print time.ctime()
t = mythread()
t.run()
print time.ctime()
$ python2 test.py
Mon Aug 15 23:12:46 2011
Traceback (most recent call last):
File "test.py", line 15, in <module>
print time.ctime()
NameError: name 'time' is not defined
В первом случае time
импортируется из основного потока, а затем дочерний процесспородил.Дочерний процесс также имеет доступ к time
, поэтому время печатается дважды.Во втором случае time
импортируется в дочерний поток.Однако родительский поток этого не видит, поэтому второй вызов time.ctime()
завершается неудачно.
Когда вы загружаете GTK из дочернего потока, родительский поток не знает об этом, поэтому вы никогда не столкнетесь с проблемами с двумя потоками, пытающимися получить доступ к библиотекам GTK (цитируя документацию GDK: «То есть толькоодин поток может использовать GTK + в любой момент времени. ").