python - 为什么在调用 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()
调用就阻塞辅助线程中的执行?
我错过了什么?
解决方案
推荐阅读
- amazon-web-services - 如何仅为特定用户提供创建 IAM 用户访问权限
- flutter - Flutter,Flare Actor,Rive,同时强制启动动画
- react-native - 对本地货币输入做出反应
- regex - php正则表达式匹配完整的url
- html - 在javascript中检查屏幕大小
- react-native - 如何创建与 expo 和 raw react-native 兼容的 NPM 包
- python-3.x - 使用 selenium 提取 WebTable
- javascript - Microsoft Graph:跨域令牌兑换仅适用于“单页应用程序”
- javascript - 与 Svg 垂直堆叠条形图反应(无第三方库)
- javascript - 使用 javascript/webSQL/SQLite 将 CSV 文件导入表