ReaL_HarDCorE
@ReaL_HarDCorE

PyQt 5: как одновременно завершить несколько потоков QThread в течение определённого времени?

Добрый день. У меня есть код на Python 3.4 с использованием PyQt 5. В нём у меня создаются несколько потоков из одного класса, унаследованного от QThread:

# -*- coding: utf-8 -*-

from sys import argv as sys_argv, exit as sys_exit
import time
from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5.QtCore import QThread


class Thread_Worker (QThread):

    def __init__ (self):
        super().__init__()
        self.isRun = True

    def run (self):
        while self.isRun:
            time.sleep(60) # Do something

class Threads_Control (QWidget):

    def __init__ (self):
        super().__init__()
        self.threads = []

        self.resize(250, 150)
        self.move(200, 200)
        self.show()

        for i in range(50):          # Создать 50 потоков
            th = Thread_Worker()
            self.threads.append(th)  # Закинуть инстанс потока в массив
            th.start()

    def stop_all_threads (self):
        for th in self.threads:        
            th.isRun = False         # Установить флаг, что поток должен остановиться
            if (not th.wait(5000)):  # Ждать завершения потока 5 секунд
                th.terminate()       # Если не завершился за это время, завершить насильно 

if __name__ == '__main__':
    app = QApplication(sys_argv)

    tc = Threads_Control()
    tc.stop_all_threads()

    sys_exit(app.exec_())


Как хотелось бы чтобы работало: Создаются 50 потоков, каждый из которых имеет флаг isRun, отвечающий за то, должен ли поток продолжать работу или нет. Затем, когда нужно их все завершить, меняем флаг у каждого из них на False, и тут же даём каждому из них 5 секунд на корректное завершение работы. Если за 5 секунд не завершились, завершаем насильно с помощью метода terminate().

Проблема в том, что метод wait(5000) у воркера блокирует основной поток на указанное время (5 сек, в моём случае) при каждой итерации цикла.

В худшем случае, чтобы завершить 50 запущенных потоков, которые не смогли завершиться сами за 5 секунд, понадобится 50 * 5 = 250 сек, то есть больше 4 минут, что абсолютно не приемлемо.

Подскажите, пожалуйста, как всем 50 потокам сообщить одновременно, что они должны завершиться в течение 5 секунд?
  • Вопрос задан
  • 1949 просмотров
Решения вопроса 1
Пригласить эксперта
Ответы на вопрос 1
@PythonDeveloper
Сначала в цикле дать всем команду на завершение. Вне цикла подождать 5 секунд. Следующим циклом завершить их принудительно.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы