gpt4 book ai didi

python - 为什么延迟会改变正在运行的 QThread 数量?

转载 作者:太空宇宙 更新时间:2023-11-03 14:42:03 25 4
gpt4 key购买 nike

以下示例程序使用 QThread 实例来运行队列中的作业。

from queue import Queue
from sys import argv
from threading import Lock
from time import sleep
from PyQt5.QtCore import QObject, QThread, pyqtSignal, pyqtSlot
from PyQt5.QtWidgets import QApplication

class Worker(QObject):
finished = pyqtSignal()

def __init__(self, number):
super().__init__()
self.number = number

@pyqtSlot()
def work(self):
while True:
job = queue.get()
if job is None:
self.finished.emit()
return
with lock:
print('worker={} job={}'.format(self.number, job))
sleep(1)

app = QApplication(argv)
lock = Lock()
queue = Queue()
threads = []
nthreads = 4
for ithread in range(nthreads):
thread = QThread()
worker = Worker(ithread + 1)
worker.moveToThread(thread)
thread.started.connect(worker.work)
worker.finished.connect(thread.quit)
thread.start()
threads += [thread]
#-----------
sleep(1e-10)
#-----------

for ijob in range(10):
queue.put(ijob + 1)

for _ in range(nthreads):
queue.put(None)
for thread in threads:
thread.wait()

通过 sleep 调用(参见标记行),所有线程都按预期运行。输出:

worker=1 job=1
worker=2 job=2
worker=3 job=3
worker=4 job=4
[…]

如果没有调用,任意数量的线程正在运行。输出:

worker=4 job=1
worker=4 job=2
worker=4 job=3
worker=4 job=4
[…]

我已经使用 Python 3.6.2 中的 PyQt 5、其他版本、可变的 sleep 持续时间、不同的语句顺序和运行的事件循环对此进行了测试。

为什么sleep调用会改变正在运行的线程数?

最佳答案

前三个工作对象容易被垃圾回收,而第四个则作为全局变量保留。 sleep 只允许每个线程有足够的时间来调用其关联工作线程的 work 方法,这将使它们全部保持事件状态(因为这些方法运行时会阻塞 while 循环) 。如果没有sleep,前三个工作线程将立即被垃圾回收,只留下第四个来处理队列。如果工作线程保存在列表中(与线程相同的方式),您应该看到所有工作线程都被利用(无论是否处于 sleep 状态)。

为了证明这就是正在发生的事情,您可以将其添加到 Worker 类中:

class Worker(QObject)
...

def __del__(self):
print('deleted:', self.number)

关于python - 为什么延迟会改变正在运行的 QThread 数量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46501921/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com