当QThread有一个事件队列时,使用exit()终止线程是否安全?

时间:2012-08-14 19:27:44

标签: python multithreading qt pyside

我使用QThread做一些定期的后台工作,源代码看起来像这样

class Worker(QObject):
    """ Separate QObject that does the work with affinity of 
        'DoStuffOnceASecond'"""
    def __init__(self):
        super(QWorker, self).__init__()

    def doWork(self):
        #... do work, post signal to consumer


class DoStuffOnceASecond(QThread):
    def __init__(self):
        super(DoStuffOnceASecond, self).__init__()   

    def run(self):
        """ Setup "pullFiles" to be called once a second"""
        self.timer= QTimer()
        self.worker = Worker()
        self.timer.setSingleShot(False)
        self.timer.timeout.connect(self.worker.doWork)
        self.timer.start(1000)
        self.exec_()

我正在寻找终止此类线程的最佳方法。一种选择是将来自主线程的信号发布到该线程,在该线程中创建一个槽。由于这些插槽作为事件循环的一部分执行,因此可以安全地拾取它们。但那时我会自我终止......而且我不确定这是否能很好地发挥作用。

或者我想知道,因为线程应该意识到它运行一个事件循环,如果它在这个线程上调用exit()是安全的吗? documentation 似乎表示这没问题:

  

调用此函数后,线程离开事件循环并从调用返回到QEventLoop :: exec()。 QEventLoop :: exec()函数返回returnCode。

认为"离开事件循环"意味着它将允许当前事件完成处理。或者QThread会立即终止吗?

这里的代码是python(pyside 1.10,python 2.7),但这可以很容易地应用于使用QThread的任何QT代码。

1 个答案:

答案 0 :(得分:1)

如果您不介意返回代码为0,则无需声明任何额外的广告位。然后,您可以使用already defined quit()广告位来调用{{1}在你的线程上。关于你“自我终止”的恐惧 - 你没有终止线程,只是退出它的事件循环。您可以通过再次调用exec()随时启动它。你仍然对你的线程很好,所以一切都应该“工作得很好”。 QThread::terminate可以立即终止,但是当上述方法失败时,这意味着杀死线程的最后绝望手段。