Как работает приоритетность потоков? (QThread)
Как работает приоритетность потоков?
Должен ли 3 поток успевать суммировать больше, или это зависит от нагруженности функции run()?
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import QThread
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
import sys
import time
import math
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(278, 152)
self.verticalLayout = QtWidgets.QVBoxLayout(Dialog)
self.verticalLayout.setObjectName("verticalLayout")
self.gridLayout = QtWidgets.QGridLayout()
self.gridLayout.setObjectName("gridLayout")
self.label_2 = QtWidgets.QLabel(Dialog)
self.label_2.setObjectName("label_2")
self.gridLayout.addWidget(self.label_2, 0, 1, 1, 1)
self.label_3 = QtWidgets.QLabel(Dialog)
self.label_3.setObjectName("label_3")
self.gridLayout.addWidget(self.label_3, 0, 2, 1, 1)
self.label = QtWidgets.QLabel(Dialog)
self.label.setObjectName("label")
self.gridLayout.addWidget(self.label, 0, 0, 1, 1)
self.label_4 = QtWidgets.QLabel(Dialog)
self.label_4.setText("")
self.label_4.setObjectName("label_4")
self.gridLayout.addWidget(self.label_4, 1, 0, 1, 1)
self.label_5 = QtWidgets.QLabel(Dialog)
self.label_5.setText("")
self.label_5.setObjectName("label_5")
self.gridLayout.addWidget(self.label_5, 1, 1, 1, 1)
self.label_6 = QtWidgets.QLabel(Dialog)
self.label_6.setText("")
self.label_6.setObjectName("label_6")
self.gridLayout.addWidget(self.label_6, 1, 2, 1, 1)
self.verticalLayout.addLayout(self.gridLayout)
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
self.label_2.setText(_translate("Dialog", "2 поток"))
self.label_3.setText(_translate("Dialog", "3 поток"))
self.label.setText(_translate("Dialog", "1 поток"))
class Thread(QThread):
def __init__(self, parent=None):
super().__init__(parent)
self._isPause = False
self.condition = QWaitCondition()
self.mutex = QMutex()
self.sum = 0
def run(self):
while True:
self.sum += 1
class Window(QDialog, Ui_Dialog):
def __init__(self):
super().__init__()
self.setupUi(self)
self.timer = QtCore.QTimer()
self.timer.timeout.connect(self.update)
self.timer.start(2000)
self.thread = Thread(self)
self.thread.start(QThread.LowestPriority)
print(self.thread.priority())
self.thread_2 = Thread(self)
self.thread_2.start(QThread.NormalPriority)
print(self.thread_2.priority())
self.thread_3 = Thread(self)
self.thread_3.start(QThread.HighestPriority)
print(self.thread_3.priority())
def update(self):
self.label_4.setText(str(self.thread.sum))
self.label_5.setText(str(self.thread_2.sum))
self.label_6.setText(str(self.thread_3.sum))
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())
Ответы (1 шт):
Автор решения: S. Nick
→ Ссылка
Я не знаю правильно ли понял ваш вопрос, но обратите внимание на следующие моменты:
- Код запускает 3 потока с приоритетами, которые вы установили. Обратите внимание, что в этом варианте нет никакой задержки в работе потока(
# self.msleep(1)-закомментировано ). Также обратите внимание на загрузку ЦП. Запуск двух таких приложений уложат интерфейс. Приоритеты работают как надо.
q1282746.py
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class Thread(QtCore.QThread):
def __init__(self, parent=None):
super().__init__(parent)
self._isPause = False
self.condition = QtCore.QWaitCondition()
self.mutex = QtCore.QMutex()
self.sum = 0
def run(self):
while True:
self.sum += 1
# self.msleep(1) # !!!
class Window(QtWidgets.QDialog):
def __init__(self):
super().__init__()
self.label_4 = QtWidgets.QLabel()
self.label_5 = QtWidgets.QLabel()
self.label_6 = QtWidgets.QLabel()
self.label_sum = QtWidgets.QLabel()
self.label_time = QtWidgets.QLabel('0')
layout = QtWidgets.QFormLayout(self)
layout.addRow(f'{"Низкий приоритет":>40}:', self.label_4)
layout.addRow(f'{"Нормальный приоритет":>35}:', self.label_5)
layout.addRow(f'{"чаще, чем Высокий приоритет":>30}:', self.label_6)
layout.addRow("", self.label_sum)
layout.addRow("", self.label_time)
self.thread = Thread(self)
self.thread.start(QtCore.QThread.LowestPriority)
print(f'LowestPriority {self.thread.priority()}:')
self.thread_2 = Thread(self)
self.thread_2.start(QtCore.QThread.NormalPriority)
print(f'NormalPriority {self.thread_2.priority()}:')
self.thread_3 = Thread(self)
self.thread_3.start(QtCore.QThread.HighestPriority)
print(f'HighestPriority {self.thread_3.priority()}:')
self.timer = QtCore.QTimer()
self.timer.timeout.connect(self.update)
self.timer.start(2000)
def update(self):
self.label_4.setText(f'{self.thread.sum:>20,}')
self.label_5.setText(f'{self.thread_2.sum:>20,}')
self.label_6.setText(f'{self.thread_3.sum:>20,}')
self.label_sum.setText(f'{self.thread.sum + self.thread_2.sum + self.thread_3.sum:>20,}')
self.label_time.setText(
f'{str(int(self.label_time.text()) + 2):>26}'
)
if int(self.label_time.text()) == 102:
self.timer.stop()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
app.setFont(QtGui.QFont("Times", 12, QtGui.QFont.Bold))
window = Window()
window.resize(450, 152)
window.show()
sys.exit(app.exec_())
- Код запускает с 1 потоком. Обратите внимание, что в этом варианте нет никакой задержки в работе потока(
# self.msleep(1)-закомментировано ). Также обратите внимание на загрузку ЦП. Запуск двух таких приложений уложат интерфейс.
q1282746-222.py
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class Thread(QtCore.QThread):
def __init__(self, parent=None):
super().__init__(parent)
self._isPause = False
self.condition = QtCore.QWaitCondition()
self.mutex = QtCore.QMutex()
self.sum = 0
def run(self):
while True:
self.sum += 1
# self.msleep(1) # !!!
class Window(QtWidgets.QDialog):
def __init__(self):
super().__init__()
self.label_4 = QtWidgets.QLabel()
# self.label_5 = QtWidgets.QLabel()
# self.label_6 = QtWidgets.QLabel()
self.label_time = QtWidgets.QLabel('0')
layout = QtWidgets.QFormLayout(self)
layout.addRow(f'{"Один поток":>40}:', self.label_4)
# layout.addRow(f'{"Нормальный приоритет":>35}:', self.label_5)
# layout.addRow(f'{"чаще, чем Высокий приоритет":>30}:', self.label_6)
layout.addRow("", self.label_time)
self.thread = Thread(self)
self.thread.start()
'''
print(f'LowestPriority {self.thread.priority()}:')
self.thread_2 = Thread(self)
self.thread_2.start(QtCore.QThread.NormalPriority)
print(f'NormalPriority {self.thread_2.priority()}:')
self.thread_3 = Thread(self)
self.thread_3.start(QtCore.QThread.HighestPriority)
print(f'HighestPriority {self.thread_3.priority()}:')
'''
self.timer = QtCore.QTimer()
self.timer.timeout.connect(self.update)
self.timer.start(2000)
def update(self):
self.label_4.setText(f'{self.thread.sum:>20,}')
# self.label_5.setText(f'{self.thread_2.sum:>20,}')
# self.label_6.setText(f'{self.thread_3.sum:>20,}')
self.label_time.setText(
f'{str(int(self.label_time.text()) + 2):>26}'
)
if int(self.label_time.text()) == 102:
self.timer.stop()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
app.setFont(QtGui.QFont("Times", 12, QtGui.QFont.Bold))
window = Window()
window.resize(450, 152)
window.show()
sys.exit(app.exec_())
- Пробуем запустить обе задачи указанные выше. Обратите внимание на загрузку ЦП - интерфейс практический лежит. Приоритеты работают как надо.
q1282746-QProcess.py
from PyQt5 import QtCore, QtGui, QtWidgets
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self._process = QtCore.QProcess(self)
self._process.start('python', ["q1282746-222.py"])
self._process2 = QtCore.QProcess(self)
self._process2.start('python', ["q1282746.py"])
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
- А теперь проделайте пункты 1, 2 и 3 предварительно раскомментировав строку
self.msleep(1)- в q1282746.py и q1282746-222.py. Также обратите внимание на загрузку ЦП. Интерфейс работает нормально. Приоритеты не работают.



