【问题标题】:When a QThread has an event queue, is it safe to terminate the thread with exit()?当 QThread 有事件队列时,使用 exit() 终止线程是否安全?
【发布时间】:2012-08-11 03:55:53
【问题描述】:

我正在使用 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代码。

【问题讨论】:

    标签: python multithreading qt pyside


    【解决方案1】:

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

    【讨论】:

    • 所以答案是“是”,它是安全的。但重要的是要注意(就像我刚刚了解到的那样),退出只是告诉事件队列在当前事件完成后停止。它不会阻塞。如果您想等待线程因quit 调用而完成,则需要调用“wait()”。
    • 是的,这是一种常见的做法。让两个线程都可以访问 QWaitCondition,并在退出事件循环时执行 wakeAll()。但这不是你问题的一部分:-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-06
    • 2014-12-14
    • 2018-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多