Вопрос по multithreading, python – Ты понимаешь этот тупик?

0

Я использую wxPython для моего GUI. вAppLogic У меня есть рабочий поток, который запускается в методе этого самого класса.

ЭтоGUI учебный класс:

<code>class GUI:
    _wx_app = None
    _main_window = None
    _app_logic = None

    def start(self):
        # bla bla bla
        self._main_window.Show()
        self._app_logic.begin()
        self._wx_app.MainLoop()

    def _cancel_listener(self):
        """Called from MainWindow, if the user has clicked the cancel
        button."""
        print("I'm leaving this scope.")
        self._app_logic.cancel()  # Should cancel the task done in
                                  # a second thread.

    def _status_listener(self, status_text):
        """Called often by the worker thread."""
        print("Here I am again.")
        if self._main_window.status.GetLabel() != status_text:
            self._main_window.status.SetLabel(status_text)
</code>

Вот способ отмены изAppLogic класс, который называется_cancel_listener сверху:

<code>    def cancel(self):
        self._shall_abort = True
        self._thread.join(self._some_time_out)
        assert self._thread.isAlive() == False
</code>

Каким-то образом, тупик сjoin а такжеGetLabel (и поэтомуMainLoop?) участвует, но я не совсем понимаю, что происходит. У кого-то есть больше понимания этого? Это было бы прекрасно!

«Каким-то образом, существует тупик с объединением». - неудивительно, что TBH :( лучше всего избегать join () в приложениях с графическим интерфейсом. В приложениях без графического интерфейса лучше всего избегать join (). Martin James

Ваш Ответ

2   ответа
2

Все инструменты GUI имеют основной поток GUI. Все они имеют специальные методы, которые позволяют вам управлять GUI-виджетами потокобезопасным способом. В мире wxPython это методы wx.CallAfter, wx.CallLater и wx.PostEvent. Я не вижу их нигде в вашем примере, поэтому то, что вы делаете, в основном приостанавливает поток графического интерфейса или вызывает что-то "неопределенное". происходить.

Вот пара статей о потоках и wxPython:

Error: User Rate Limit ExceededjoinError: User Rate Limit ExceededGUIError: User Rate Limit ExceededGetLabelError: User Rate Limit Exceeded rynd
Error: User Rate Limit Exceeded
2

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

Когда вы вызываете метод cancel () из потока GUI, он устанавливает переменную abort, а затем ожидает завершения другого потока с помощьюself._thread.join(), поэтому никакие дальнейшие сообщения не обрабатываются, пока другой поток не остановится. Но другой поток продолжает ждать ответа на свое сообщение GetLabel () - & gt; бинго!

Error: User Rate Limit ExceededGUIError: User Rate Limit ExceededGetLabelError: User Rate Limit ExceededMainLoopError: User Rate Limit ExceededMainLoopError: User Rate Limit ExceededMainWindowError: User Rate Limit Exceeded_cancel_listenerError: User Rate Limit ExceededcancelError: User Rate Limit ExceededGetLabelError: User Rate Limit ExceededMainLoopError: User Rate Limit Exceeded rynd

Похожие вопросы