ошибки исключения потока Python при выходе из всей программы - PullRequest
1 голос
/ 02 ноября 2010

Привет, ребята,

Я разрабатываю графический интерфейс с Python 2.4.3 и wxpython. Все работает отлично, за исключением, когда я выхожу из основной программы (закройте главное окно графического интерфейса). Самое странное, что иногда возникает такая ошибка, а иногда ее вообще нет. Хотя я нашел те же сообщения об ошибках из списка рассылки python (ссылка http://bugs.python.org/issue1722344,, я не уверен, совпадает ли мой случай с этим). Я не знаю, как это наконец решается и что я должен сделать, чтобы преодолеть эту проблему.

Сообщение об ошибке от консоли выглядит следующим образом.

Exception in thread Thread-1 (most likely raised during interpreter shutdown):
Traceback (most recent call last):
  File "/usr/lib/python2.4/threading.py", line 442, in __bootstrap
  File "/opt/company/workspace/username/application/src/mainwidget.py", line 1066, in run
  File "/usr/lib/python2.4/Queue.py", line 89, in put
  File "/usr/lib/python2.4/threading.py", line 237, in notify
exceptions.TypeError: exceptions must be classes, instances, or strings (deprecated), not NoneType
Unhandled exception in thread started by 
Error in sys.excepthook:

Original exception was:

Следующее является частью моего кода (код, связанный с потоками, завершен, для остальных я извлекаю основные операции). когда я использую графический интерфейс для запуска внешнего подпроцесса, одновременно создается объект wx.TextCtrl. Этот объект wx.TextCtrl используется для ввода и вывода на печать внешнего подпроцесса

class BashProcessThread(threading.Thread):
    def __init__(self, readlineFunc):
        threading.Thread.__init__(self)
        self.readlineFunc = readlineFunc
        self.lines = []
        self.outputQueue = Queue.Queue()
        self.setDaemon(True)

    def run(self):
        while True:
           line = self.readlineFunc()
           self.outputQueue.put(line)
           if (line==""):
            break
        return ''.join(self.lines)

    def getOutput(self):
        """ called from other thread """            
        while True:
            try:
                line = self.outputQueue.get_nowait()
                lines.append(line)
            except Queue.Empty:
                break
        return ''.join(self.lines)

class ExternalProcWindow(wx.Window):
    def __init__(self, parent, externapp):
        wx.Window.__init__(self, parent, -1, pos=wx.DefaultPosition, size = wx.Size(1200, 120))
        self.externapp=externapp
        self.prompt = externapp.name.lower() + '>>'
        self.textctrl = wx.TextCtrl(self, -1, '', size= wx.Size(1200, 120), style=wx.TE_PROCESS_ENTER|wx.TE_MULTILINE)
        self.default_txt = self.textctrl.GetDefaultStyle()
        self.textctrl.AppendText(self.prompt)
        self.outputThread = BashProcessThread(self.externapp.sub_process.stdout.readline)
        self.outputThread.start()
        self.textctrl.SetFocus()
        self.__bind_events()         
        self.Fit()

    def __bind_events(self):
        self.Bind(wx.EVT_TEXT_ENTER, self.__enter)

    def __enter(self, e):
        nl=self.textctrl.GetNumberOfLines()
        ln =  self.textctrl.GetLineText(nl-1)
        ln = ln[len(self.prompt):]     
        self.externapp.sub_process.stdin.write(ln+"\n")
        time.sleep(.3)
        self.textctrl.AppendText(self.outputThread.getOutput())

class ExternApp:
    def launch(self):
        self.sub_process = subprocess.Popen(launchcmd, stdin=subprocess.PIPE, 
                stdout=subprocess.PIPE, stderr=subprocess.PIPE)

1 Ответ

4 голосов
/ 02 ноября 2010

Проблема вызвана использованием threading.Thread.setDaemon. Потоки set daemonic не препятствуют выходу интерпретатора Python, но они все еще продолжают работать . Поскольку Python очищает среду до завершения процесса, потоки могут столкнуться с проблемами при удалении из-под них вещей. Возникает исключение, которое класс потока пытается распечатать для вашего удобства, но затем оно тоже завершается сбоем, поскольку процесс завершается.

Вы могли бы попытаться заставить замолчать исключение, но это сложно (и если поток делает что-то существенное, это может скрыть реальную проблему. Однако, не здесь). Или вы можете попросить поток остановить перед выход, а не установить поток демон. Или вы можете просто избежать использования потоков вообще. Я не помню, имеет ли wxPython удобный механизм для получения выходных данных процесса или даже для асинхронного ввода-вывода, но многие инструментарии GUI делают. И всегда есть Twisted, который делает все это для вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...