首页 > 解决方案 > 为什么在调用 QThread.quit() 和随后的 QThread.wait() 时会出现竞争?

问题描述

使用PySide2,我有一个辅助线程运行后台事件循环。关闭我的应用程序后,我想quit()使用辅助线程并wait()为其完成事件。

但是,一旦我调用wait(). 为了演示这个问题,我创建了一个带有子类的小型示例应用程序,该应用程序QThread通过调用运行事件循环exec_(),然后使用一些模拟清理打印来模拟较长的退出时间。

import sys
import time

from PySide2.QtCore import QThread
from PySide2.QtWidgets import QApplication, QMainWindow


class AuxThread(QThread):

    def __init__(self):
        super().__init__()

    def run(self):
        print("Starting AuxThread")
        self.exec_()
        print("Stopping AuxThread")
        iteration = 0
        # Simulate a long time for thread finish
        while iteration < 100:
            iteration += 1
            print(f"{iteration} cleanup loops in {QThread.currentThread()}")


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.thread().setObjectName("main thread")

        self.aux_thread = AuxThread()
        self.aux_thread.setObjectName("aux thread")

        self.aux_thread.start()

    def closeEvent(self, event):
        print(f"Quitting aux_thread from {QThread.currentThread()}")
        self.aux_thread.quit()

        # Increasing this time allows the run() function to complete
        # If this time is too short, then execution hangs forever
        time.sleep(0.001)

        print(f"blocking thread {QThread.currentThread()}")
        self.aux_thread.wait()
        print(f"aux_thread is joined")


if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

该函数的输出如下所示,打印的迭代次数会根据时间不同而不同。

Starting AuxThread
Quitting aux_thread from <PySide2.QtCore.QThread(0x7fcc9cfd12b0, name = "main thread") at 0x11c4f1580>
Stopping AuxThread
1 cleanup loops in <__main__.AuxThread(0x7fcc9cfe5e40, name = "aux thread") at 0x11c4f15c0>
2 cleanup loops in <__main__.AuxThread(0x7fcc9cfe5e40, name = "aux thread") at 0x11c4f15c0>
... [output elided] ...
72 cleanup loops in <__main__.AuxThread(0x7fcc9cfe5e40, name = "aux thread") at 0x11c4f15c0>
73 cleanup loops in <__main__.AuxThread(0x7fcc9cfe5e40, name = "aux thread") at 0x11c4f15c0>
blocking thread <PySide2.QtCore.QThread(0x7fcc9cfd12b0, name = "main thread") at 0x11c4f1580>

文档说“QThread.wait()阻塞线程直到 QThread 完成执行(即当它从返回时run())”

有趣的是,他们没有提到这里阻塞了哪个线程,但是阻塞你正在等待的 QThread 是没有意义的。我认为aux_thread.wait()应该只阻塞主线程,为什么一wait()调用就阻塞辅助线程中的执行?

我错过了什么?

标签: pythonmultithreadingqtqthreadpyside2

解决方案


推荐阅读