当我最多只有4个线程时,qthread如何管理正在处理的线程数? 例如,假设我有100个长处理任务。当我遍历100个树视图项并发出一个Qthread来处理每个任务时,会发生什么?它是否自动确定我只有4个线程,并在4个可用线程中处理100个线程
好奇。 谢谢
import os
import sys
import time
import random
from PySide2 import QtCore, QtGui, QtWidgets
class TaskThread(QtCore.QThread):
finished = QtCore.Signal(object)
def __init__(self, index):
super(TaskThread, self).__init__()
self._index = index
def runTask(self, task):
self._task = task
def run(self):
t = random.randint(0,4)
time.sleep(t)
self.finished.emit(self._index)
class ExampleDialog(QtWidgets.QDialog):
def __init__(self):
super(ExampleDialog, self).__init__()
self.itemModel = QtGui.QStandardItemModel()
self.uiListView = QtWidgets.QListView()
self.uiListView.setModel(self.itemModel)
self.mainLayout = QtWidgets.QVBoxLayout(self)
self.mainLayout.addWidget(self.uiListView)
self.populateItems()
def populateItems(self):
self.threads = []
for x in range(100):
output = 'C:/Users/JokerMartini-Asus/Desktop/Trash/thumbs/IMG_409{}.jpg'.format(x)
# Item
item = QtGui.QStandardItem('{}'.format(x))
item.setData(QtGui.QPixmap(), QtCore.Qt.DecorationRole)
item.setData(output, QtCore.Qt.UserRole)
self.itemModel.appendRow(item)
mIndex = QtCore.QPersistentModelIndex(self.itemModel.indexFromItem(item))
tt = TaskThread(mIndex)
self.threads.append(tt)
tt.start()
tt.finished.connect(self.processFinished)
def processFinished(self, index):
if index.isValid():
model = index.model()
model.setData(index, '{} updated'.format(index.row()), QtCore.Qt.DisplayRole)
if __name__ == '__main__':
pass
app = QtWidgets.QApplication(sys.argv)
window = ExampleDialog()
window.resize(300,600)
window.show()
window.raise_()
sys.exit(app.exec_())
注意:我的回答仅基于经验实验和线程的基本知识。对于线程的底层实现,我没有足够的知识来提供我所表达的内容的可靠资源,也不能证明这在所有支持Qt的平台上都是有效的(我在Linux上)。
<> P>在处理线程时有两件重要的事情要考虑,即使Qt绑定:从根本上说,没有绝对顺序,在python中,线程没有严格的优先级(由于上述原因):从理论上讲,处理是[几乎]按照线程启动的顺序进行的,但结果可能会因每个线程处理的“速度”而有所不同,即使对于相同的操作也是如此。一旦一个线程将控制权释放给GIL,“下一个”线程就会得到它
通过对代码添加以下更改,您可以看到更可靠的结果:
注意:上面的代码将阻塞UI,
hasPendingEvents
被认为是过时的,因为线程的并发性,出于同样的原因,不鼓励使用processEvents
;只考虑教育目的。这意味着三件事:
真正的并行性只能通过多进程实现,但问题是进程与线程不同,不共享内存。这并不意味着这是完全不可能的:thislink声称他们实现了对Qt信号/插槽机制的适当的多处理支持,但我从未尝试过,也不能说它真的有效(特别是考虑到该链接已经很旧)
注意:您不应该在线程启动后连接它的信号,特别是如果该线程可能立即返回(
time.sleep(0)
);将tt.finished.connect
行移动到tt.start()
之前。相关问题 更多 >
编程相关推荐