signal.signal не работает с потоковой обработкой, или другая причина, по которой я не могу использовать Ctrl-C, чтобы остановить мой многопоточный код Python?

#python #multithreading #python-multithreading #sigterm

#python #многопоточность #python-многопоточность #sigterm

Вопрос:

Я бился головой об это все выходные, посвященные Дню труда. Приведенный ниже код не останавливается с помощью Ctrl-C. Должно быть, я делаю что-то безмозглое и больше не вижу этого. Это не только не останавливается, но я никогда не получаю сообщение обработчика сигнала, "Interrupted by %d, shutting down"

Я слышу такие термины, как «заблокирован», но я не знаю, что они означают. Мой SIGTERM каким-то образом «заблокирован»? Я также не понимаю разницы между killpill.подождите и уничтожьте pill.is_set(). Но это кажется второстепенной проблемой. Поскольку я, похоже, никогда не улавливаю SIGTERM, метод killpill не должен иметь значения.

Я использую Python 3.8.5 в Windows 10, работающий в PowerShell.

 import signal
import logging
import threading

logging.basicConfig(level=logging.DEBUG,
                    format='[%(levelname)s] (%(threadName)-10s) %(message)s')


def quit(signo, _frame):  # Graceful exit when we get ^C
    print("Interrupted by %d, shutting down" % signo)
    killpill.set()


def doit():
    try:
        while not(killpill.wait(1)):
            logging.debug( "starting ... "   str( killpill.is_set() ))
            time.sleep(1)
            logging.debug( "working ... "   str( killpill.is_set()) )
    except KeyboardInterrupt:
        logging.debug("KeyboardInterrupt stopping mouse_info")

        
def main():
    global killpill
    killpill = threading.Event()
    t1=threading.Thread(name='t1',target=doit)
    t1.daemon=True
    t1.start()
    t1.join()
    while True:
        time.sleep(1)


if (__name__ == '__main__'):
    for sig in ('TERM', 'INT', 'BREAK', 'ABRT'):
        signal.signal(getattr(signal, 'SIG' sig), quit)
    main()
  

Любая полезная информация была бы высоко оценена. Вывод

 [DEBUG] (t1        ) working ... False
[DEBUG] (t1        ) starting ... False
[DEBUG] (t1        ) working ... False
[DEBUG] (t1        ) starting ... False
  

Комментарии:

1. Я попробовал еще одну вещь перед сном, основываясь на других ссылках. Я внес следующие изменения: ‘killpill.wait (1)’ стал ‘killpill.is_set()’ и в while True цикле main() я добавил t1.join(10) if not(t1.is_alive()): break Однако, я понятия не имею, почему это сработало, когда оригинал этого не сделал.

2. вы проверяете KeyboardInterrupt в потоках, но у них нет доступа к клавиатуре. Я бы использовал это в основном потоке.