QThread异常管理和线程竞争

时间:2016-10-11 17:33:55

标签: python multithreading qt exception-handling pyside

我有一个使用QThread的GUI(PySide)应用程序。我的QThread中有一个信号,当发生异常时会发出信号,这样我就可以在主线程中处理异常。但是,仍然执行启动线程的其余函数。我尝试使用wait函数来阻止执行,但它不起作用。这是我的实施:

QThread女儿

class LongTaskThread(QtCore.QThread):
    task_finished = QtCore.Signal()
    task_failed = QtCore.Signal(Exception)

    def __init__(self, allow_log=True, test_mode=False, parent=None):
        QtCore.QThread.__init__(self, parent)

    def run(self):
        self.task_failed.emit(Exception())

    def wait_with_gui_refresh(self):
        while self.isRunning():
            time.sleep(0.1)
            if not self.test_mode:
                QtGui.QApplication.processEvents()

主要帖子

def test():
   my_thread = LongTaskThread()
   my_thread.task_finished.connect(on_finished)
   my_thread.task_failed.connect(on_failed)
   my_thread.start()
   # my_thread.wait()    <---- tentative 1
   # my_thread.wait_with_gui_refresh()    <---- tentative 2
   print('bla bla bla bla')

def on_finished)():
   pass

def on_failed(err):
  raise err

我预计print永远不会被点击,但无论我使用wait功能还是wait_with_gui_refresh功能,或者什么都没有,打印始终会被打印。

如何在QThread内引发异常时停止测试功能?

1 个答案:

答案 0 :(得分:1)

test函数中,事件序列如下:

  1. 线程开始
  2. 线程的run方法称为
  3. task_failed信号以异步方式发送 (即它已发布到接收方的事件队列中)
  4. 线程的run方法返回
  5. 如果此处调用了线程的wait方法,它将立即返回True,因为没有什么可以等待的(即run已经返回)
  6. 打印一条消息,test返回
  7. 控制返回事件循环,并处理task_failed信号
  8. on_failed
  9. 引发了异常

    在这里很难看到任何反对意见。据推测,当工作线程运行时,您不想阻止gui,因此以异步方式处理任何异常都是完全合理的。但是为了实现这一点,控制必须返回主线程的事件循环 - 这意味着test函数必须立即返回。如果要在线程启动后运行某些代码,请将插槽连接到其started信号。