Как правило, лучше избегать потоков, когда это возможно. Очень сложно правильно написать потоковое приложение, и еще труднее узнать, правильно ли вы это сделали. Поскольку вы пишете приложение с графическим интерфейсом, вам проще представить, как это сделать, поскольку вы уже должны писать свое приложение в асинхронной среде.
Важно понимать, что приложение с графическим интерфейсом ничего не делает. Он проводит большую часть своего времени, ожидая, пока ОС скажет ему, что что-то произошло. Вы можете делать много вещей в этот простой, если вы знаете, как писать долго работающий код, чтобы он не блокировался.
Вы можете решить исходную проблему, используя тайм-аут; указание вашей графической среде для вызова некоторой функции после задержки, а затем сброс этой задержки или запуск другого отложенного вызова.
Другой распространенный вопрос - как общаться по сети в приложении с графическим интерфейсом. Сетевые приложения похожи на приложения с графическим интерфейсом в том смысле, что они много ждут. Использование сетевой инфраструктуры ввода-вывода (например, Twisted ) упрощает совместное ожидание обеих частей приложения, а не конкуренции, и снова устраняет необходимость в дополнительных потоках.
Долгосрочные вычисления могут быть записаны итеративно, а не синхронно, и вы можете выполнять свою обработку, пока графический интерфейс не используется. Вы можете использовать генератор, чтобы сделать это довольно легко в Python.
def long_calculation(param, callback):
result = None
while True:
result = calculate_next_part(param, result)
if calculation_is_done(result):
break
else:
yield
callback(result)
Вызов long_calculation
даст вам объект генератора, а вызов .next()
для объекта генератора будет запускать генератор, пока он не достигнет либо yield
, либо return
. Вы просто скажете инфраструктуре графического интерфейса для вызова long_calculation(some_param, some_callback).next
, когда у нее будет время, и в итоге ваш обратный вызов будет вызван с результатом.
Я не очень хорошо знаю GTK, поэтому не могу сказать, какие функции gobject вы должны вызывать. Однако с этим объяснением вы сможете найти необходимые функции в документации или, в худшем случае, обратиться к соответствующему каналу IRC.
К сожалению, нет хорошего общего ответа. Если вы поясните, что именно вы пытаетесь сделать, было бы проще объяснить, почему вам не нужны потоки в этой ситуации.