代码之家  ›  专栏  ›  技术社区  ›  Doug T.

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

  •  2
  • Doug T.  · 技术社区  · 14 年前

    我正在使用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 回复  |  直到 14 年前
        1
  •  1
  •   Matteo Italia    9 年前

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