PySide QtCore.QThreadPool 和 QApplication.quit() 导致挂起?

Posted

技术标签:

【中文标题】PySide QtCore.QThreadPool 和 QApplication.quit() 导致挂起?【英文标题】:PySide QtCore.QThreadPool and QApplication.quit() causes hangs? 【发布时间】:2013-05-06 22:56:59 【问题描述】:

我想使用 Qt 的 QThreadPool,但如果队列中的工作人员在调用 QApplication.quit() 之前没有完成,它似乎会挂起我的应用程序。谁能告诉我我在下面简化的测试用例中是否做错了什么?

import logging
log = logging.getLogger(__name__)

import sys

from PySide import QtCore

import time

class SomeWork(QtCore.QRunnable):
    def __init__(self, sleepTime=1):
        super(SomeWork, self).__init__()
        self.sleepTime = sleepTime

    def run(self):
        time.sleep(self.sleepTime)
        print "work", QtCore.QThread.currentThreadId()

def _test(argv):
    logging.basicConfig(level=logging.NOTSET)

    app = QtCore.QCoreApplication(argv)

    pool = QtCore.QThreadPool.globalInstance()

    TASK_COUNT = int(argv[1]) if len(argv) > 1 else 1

    mainThread = QtCore.QThread.currentThreadId()
    print "Main thread: %s"%(mainThread)
    print "Max thread count: %s"%(pool.maxThreadCount())
    print "Work count: %s"%(TASK_COUNT)

    for i in range(TASK_COUNT):
        pool.start(SomeWork(1))

    def boom():
        print "boom(); calling app.quit()"
        app.quit()

    QtCore.QTimer.singleShot(2000, boom)

    #import signal
    #signal.signal(signal.SIGINT, signal.SIG_DFL)

    return app.exec_()

if __name__ == '__main__':
    sys.exit(_test(sys.argv))

要清楚,这是我得到的输出:

(env)root@localhost:# python test_pool.py 1
Main thread: 3074382624
Max thread count: 1
Work count: 1
work 3061717872
boom(); calling app.quit()

(env)root@workshop:/home/workshop/workshop/workshop# python test_pool.py 20
Main thread: 3074513696
Max thread count: 1
Work count: 20
work 3060783984
boom(); calling app.quit()

它在第二个命令上永远挂起,但不是第一个。

感谢您提供的任何帮助。

编辑:

明确地说,我希望如果 app.quit() 在线程位于线程队列中时被调用,它们不会运行。已经运行的线程应该运行完成。然后,应用程序应该关闭。 此示例在 Windows 计算机上也失败了 此示例适用于同一台 Windows 机器,但使用 PyQt4

【问题讨论】:

【参考方案1】:

在 exec() 修复问题之前将其添加到 _test(),尽管所有线程都在运行:

def waitForThreads():
    print "Waiting for thread pool"
    pool.waitForDone()
app.aboutToQuit.connect(waitForThreads)

【讨论】:

以上是关于PySide QtCore.QThreadPool 和 QApplication.quit() 导致挂起?的主要内容,如果未能解决你的问题,请参考以下文章

PySide和PySide2之间的QKeySequence区别

PySide2兼容PySide1的补丁代码

pySide: ExtensionLoader_Pyside_QtGUI.py 找不到指定的模块

Python/pyside,pyqt(pyside,pyqt optional): 控制文本选择的函数

当 slot 函数具有默认参数=None 时,PySide2 的行为与 PySide 不同

python3的Pyside-uic?