你明白这个僵局?(Do you understand this deadlock?)

2019-07-29 08:45发布

我使用wxPython的我的GUI。 在AppLogic类我有一个是在这个类的方法运行工作线程。

这是GUI类:

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)

下面是来自取消方法AppLogic它由所谓类_cancel_listener从上方:

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

不知何故,有一个僵局joinGetLabel (因此MainLoop参与?),但我真的不明白是怎么回事。 是否有人有更深入地了解这一点? 那太好了!

Answer 1:

所有的GUI工具包有一个主界面线程。 它们都具有特殊的方法,使您操作GUI控件在线程安全的方式。 在wxPython的世界里,这些方法都是wx.CallAfter,wx.CallLater和wx.PostEvent。 我没有看到你的榜样的任何地方,所以你在做什么,基本上暂停GUI线程或导致出现一些“不确定”。

这里有一对夫妇的上线和wxPython的文章:

  • http://wiki.wxpython.org/LongRunningTasks
  • http://www.blog.pythonlibrary.org/2010/05/22/wxpython-and-threads/


Answer 2:

我走了我的专业在这里,但我怀疑的wxPython就像其他工具包由通过GUI线程发送消息到子窗口,然后等待着答案。 如果是这样的情况下,GetLabel()或SetLabel()方法必须经过主消息循环(== GUI线程),并停止调用线程,直到答案用武之地。

当你调用取消()从GUI线程,它设置中止变量,然后等待其他线程结束与self._thread.join()因此没有进一步的消息进行处理,直到另一线程已停止。 但其他线程持续等待答案的GetLabel()消息 - >宾果!



文章来源: Do you understand this deadlock?