Подтвердить что ты не робот

Закрытие всех потоков с помощью прерывания клавиатуры

То, что я пытаюсь сделать здесь, это использовать прерывание клавиатуры для выхода из всех текущих потоков в программе. Это сокращенная версия моего кода, где создается поток:

for i in taskDictionary:
    try:
        sleep(60)
        thread = Thread(target = mainModule.executeThread)
        thread.start()
    except KeyboardInterrupt:
        thread.__stop()

Сама программа намного сложнее, и она содержит множество различных переменных, которые влияют на потоки и даже имеют возможность запускаться в последовательном режиме, где задачи не являются потоковыми, но вместо этого запускаются один за другим, поэтому будь то некоторые проблемы с этой небольшой вариацией, которую я только что вызвал. Я сделал это таким образом, чтобы получить результаты 50/50. Прерывания будут работать, но потоки никогда не будут чисто выходить. Иногда они продолжали идти, но останавливали выполнение будущих потоков, иногда они выходили с массивной ошибкой в ​​отношении прерывания, в других случаях прерывания ничего не делали. В прошлый раз, когда я запускал эту программу, программа прекратила выполнение любых будущих потоков, но не остановила текущий поток. Есть ли способ выйти из потоков, не входя в модуль, который фактически выполняет поток?

4b9b3361

Ответ 1

Аналогичный вопрос: "Как вы убиваете поток?"

Вы создаете обработчик вывода в своем потоке, который управляется объектом блокировки или события из модуля потоковой передачи. Затем вы просто удаляете блокировку или сигнализируете объект события. Это сообщает, что поток должен прекратить обработку и выйти изящно. После передачи потока в вашей основной программе осталось только использовать метод thread.join() в main, который будет ждать завершения потока.

Краткий пример:

import threading
import time

def timed_output(name, delay, run_event):
    while run_event.is_set():
        time.sleep(delay)
        print name,": New Message!"


def main():
    run_event = threading.Event()
    run_event.set()
    d1 = 1
    t1 = threading.Thread(target = timed_output, args = ("bob",d1,run_event))

    d2 = 2
    t2 = threading.Thread(target = timed_output, args = ("paul",d2,run_event))

    t1.start()
    time.sleep(.5)
    t2.start()

    try:
        while 1:
            time.sleep(.1)
    except KeyboardInterrupt:
        print "attempting to close threads. Max wait =",max(d1,d2)
        run_event.clear()
        t1.join()
        t2.join()
        print "threads successfully closed"

if __name__ == '__main__':
    main()

Если вам действительно нужна функциональность убийства потока, используйте многопроцессорность. Он позволяет отправлять SIGTERM в отдельные "процессы" (он также очень похож на модуль потоковой передачи). Вообще говоря, потоковая передача выполняется, когда вы привязаны к IO, а многопроцессорность выполняется, когда вы действительно связаны с процессором.