【问题标题】:PySide timers/threading crashPySide 计时器/线程崩溃
【发布时间】:2013-08-22 00:15:47
【问题描述】:

我编写了一个 PySide Windows 应用程序,它使用 libvlc 来显示视频、记录击键并将这些击键的汇总信息写入文件。我遇到了两个导致应用程序崩溃的错误(此处的其他问题 -> https://stackoverflow.com/questions/18326943/pyside-qlistwidget-crash)。

应用程序每隔五分钟在视频上写入一次击键文件。用户可以更改播放速度,让五分钟的间隔可能需要多于或少于五分钟;它不受计时器控制。

在写入文件时视频会继续播放,因此我创建了一个继承自 threading.Thread 的对象来创建文件 - IntervalFile。关于要写入的文件的一些信息在构造函数中传递; IntervalFile 根本不访问其父级(主 QWidget)。这是我在应用程序中使用的唯一线程对象。任何地方都没有声明计时器。

应用程序会间歇性地崩溃,我会收到以下消息:“QObject::killTimers: timers cannot be stop from another thread”。

创建IntervalFile的代码是(CustomWidget的一部分,继承自QWidget):

def doIntervalChange(self):
  ...
  ifile = IntervalFile(5, filepath, dbpath) # db is sqlite, with new connection created within IntervalFile
  ifile.start()
  #end of def

doIntervalChange 使用信号从 QWidget 中调用。 间隔文件是:

class IntervalFile(threading.Thread):
  def __init__(self, interval, filepath, dbpath):
    # declaration of variables

    threading.Thread.__init__(self)

  def run(self):
    shutil.copy('db.local', self.dbPath) # because db is still being used in main QWidget
    self.localDB = local(self.dbPath) # creates connection to sqlite db, with sql within the object to make db calls easier

    # query db for keystroke data
    # write file

    self.localDB.close()
    self.localDB = None

    os.remove(self.dbPath) # don't need this copy anymore

当 ifile.start() 被注释掉时,我没有看到 killTimers 崩溃。有什么建议?请注意,崩溃似乎是随机的;有时我可以使用该应用程序(只是不断地反复按下相同的按键)一个小时而不会崩溃,有时它会在前几个间隔内。由于重现崩溃的困难,我认为这些代码行是问题所在,但我不是 100% 确定。

【问题讨论】:

    标签: multithreading pyqt pyside


    【解决方案1】:

    我很确定您需要保存对线程对象的引用。当你的doIntervalChange() 方法完成时,没有任何东西持有对线程对象(ifile)的引用,因此它可以被垃圾收集。大概这就是崩溃随机发生的原因(如果线程在对象被垃圾收集之前完成了它的任务,那么你就没有问题)。

    不确定是什么在创建 QTimers,但我相当确定这不会影响我提出的解决方案!

    所以在 doIntervalChange() 中保存对 ifile 的引用到一个列表中,并在线程完成执行时定期清理该列表。看看这个以获得一个想法(如果该帖子中出现了清理线程的更好方法,请实现它!):Is there a more elegant way to clean up thread references in python? Do I even have to worry about them?

    【讨论】:

    • 我贴的代码被简化了;在发布问题之前,我实际上已经尝试过这个。感谢您的尝试
    • 啊。非常值得一试!您是否有机会发布一个显示问题的简单示例?
    • 这个项目很久以前就到期了,我最终用我更熟悉的语言重写了整个应用程序。它相对复杂,仅将其简化为一个简单的示例会很耗时,而且我现在没有动力去做。感谢您尝试提供帮助,这让我非常沮丧。
    猜你喜欢
    • 1970-01-01
    • 2014-07-06
    • 1970-01-01
    • 1970-01-01
    • 2022-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多