Python: установка sys.stdout для wx.TextCtrl с помощью Process / Thread приводит к сбоям - PullRequest
0 голосов
/ 15 сентября 2010

У меня есть wx-gui, который передает stdout / stderr двум различным текстовым элементам управления. В программе я создаю процесс для запуска некоторого кода обработки данных, и у меня есть поток, который присоединяется к процессу и изменяет глобальное состояние, когда процесс завершается.

import multiprocessing as mp
from  threading import Thread

t = Thread(target=self.join_proc)
self.process = mp.Process(target=self.currentProc.Run, args=(0,))
self.process.start()
t.start()

def join_proc(self):
    self.process.join()
    self.state.transition(SIMULATION_ACTIVE)

Проблема в том, что при первом использовании stdout после объединения программа аварийно завершает работу в одном из нескольких вариантов, когда GTK жалуется / прерывает / segfaults из-за различных ошибок, которые происходят в textctrls, например:

(python:15592): Gtk-WARNING **: Invalid text buffer iterator: either the iterator is
uninitialized, or the characters/pixbufs/widgets in the buffer have been modified
since the iterator was created.

Это пахнет как проблема с многопоточностью, но я не могу понять, как обойти эту проблему. Я попытался установить для stdout / stderr значение по умолчанию sys.__std[err|out]__, пока процесс / поток существует, но это не помогает. В настоящее время у меня есть оболочка для textctrls, которая заботится о разветвлении вызова flush () в stdout / stderr, который ничего не делает. Эта функция чувствует, что она может содержать решение, то есть сбрасывать до / после того, как что-то умное с textctrl.

Как я могу использовать объекты textctrl, чтобы это работало? В качестве альтернативы, что является лучшим вариантом для выполнения бита процесса / обратного вызова, чем моя текущая настройка процесса / присоединения к потоку?

1 Ответ

2 голосов
/ 07 мая 2011

Я недавно решил похожую проблему.Ответ: используйте Queues .Вы можете увидеть мой код в приложении wxpython здесь .Короче говоря, вам нужно создать экземпляр multiprocessing.Queue и иметь слушатель и рабочую функцию, которые будут читать и писать в эту очередь соответственно.

...