【问题标题】:Python + PyQt + Threads | Destructor never called, no other references leftPython + PyQt + 线程 |从未调用析构函数,没有其他引用
【发布时间】:2015-02-06 20:11:23
【问题描述】:

在这个伪代码中,o 的析构函数从未被调用。

class MyObj():
   def __del__():
      print "Destroyed!"
      do_upon_death()

def parse():
   o = MyObj()
   print "Ok so far..."
   raise Exception

run_in_QThread(parse)

do_other_things()

我看到终端上打印了异常,但o 似乎没有被垃圾收集。解释器不会在异常时退出(主线程继续运行)。

这背后的全部目的是在发生异常时能够在析构函数中进行某些清理。

另一种解释方式是使用不同的模式:

try:
   run_in_thread(parse)
except:
   print "Will I ever get printed?"

parse 中发生的异常不会被捕获。

更进一步:

with MyContextManager() as manager:
    run_in_thread(lambda: do_something(manager))

这里manager.__exit__() 将被调用所有None 参数,就好像代码干净地完成一样,即使do_something 中存在异常。

这样做的目的是因为我正在运行某些任务,这些任务可能由于太多不同的原因而失败,并且这些任务可以部分在主线程中完成,部分在工作线程中完成。两者都可能失败。

所以我最初的想法是在任务运行时保留对对象的引用,因此如果任务通过退出上下文或异常完成,引用将会丢失,最终会运行析构函数。

我正在尝试跟踪这些任务,并在 GUI 上显示哪些任务仍在执行其工作的可视指示器。

【问题讨论】:

  • 阅读__del__的文档。
  • 我阅读了文档。有更深层次的想法吗?

标签: python multithreading garbage-collection pyqt


【解决方案1】:

你可以在异常引发后捕获它并做你想做的事情

try:
   o = MyObj()
   print "Ok so far..."
   raise Exception

except Exception:
   del o

如果没有引发异常,则使用这种形式:

finaly:
   del o

如果你只需要保持线程活着,可能,你应该使用:Thread.sleep()

据我所知,Thread 只是 parse(),所以你需要通过 emit() 创建关于删除的信号并在主线程中发送它

我相信捕获析构函数不是最好的决定,捕获一些信号会更好。请添加更多信息,说明您为什么要这样做。

【讨论】:

  • 我刚刚添加了更多细节。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-12-23
  • 1970-01-01
  • 1970-01-01
  • 2012-09-17
  • 2019-10-05
  • 2014-08-22
  • 1970-01-01
相关资源
最近更新 更多