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

Как остановить передачу SIGINT на подпроцесс в python?

Мой python script перехватывает сигнал SIGINT с помощью модуля process для предотвращения преждевременного выхода, но этот сигнал передается подпроцессу, который я открываю с помощью Popen. есть ли способ предотвратить передачу этого сигнала на подпроцесс, чтобы он также не вышел преждевременно, когда пользователь нажимает ctrl-c?

4b9b3361

Ответ 1

Вы можете повторно назначить роль ctrl-c с помощью модуля tty, который позволяет вам манипулировать назначением сигналов. Однако имейте в виду, что, если вы не вернете их так, как они были до их изменения, они будут сохраняться для всего сеанса оболочки даже после выхода программы.

Вот простой фрагмент кода, чтобы вы начали, сохраняя старые настройки tty, повторно назначая ctrl-c на ctrl-x, а затем восстанавливая предыдущие настройки tty после выхода.

import sys
import tty

# Back up previous tty settings
stdin_fileno = sys.stdin.fileno()
old_ttyattr = tty.tcgetattr(stdin_fileno)

try:
    print 'Reassigning ctrl-c to ctrl-x'

    # Enter raw mode on local tty
    tty.setraw(stdin_fileno)
    raw_ta = tty.tcgetattr(stdin_fileno)
    raw_ta[tty.LFLAG] |= tty.ISIG
    raw_ta[tty.OFLAG] |= tty.OPOST | tty.ONLCR

    # ^X is the new ^C, set this to 0 to disable it entirely
    raw_ta[tty.CC][tty.VINTR] = '\x18'  

    # Set raw tty as active tty
    tty.tcsetattr(stdin_fileno, tty.TCSANOW, raw_ta)

    # Dummy program loop
    import time
    for _ in range(5):
        print 'doing stuff'
        time.sleep(1)

finally:
    print 'Resetting ctrl-c'
    # Restore previous tty no matter what
    tty.tcsetattr(stdin_fileno, tty.TCSANOW, old_ttyattr)

Ответ 2

Обработчики сигналов наследуются при запуске подпроцесса, поэтому, если вы используете сигнальный модуль для игнорирования SIGINT (signal.signal(signal.SIGINT, signal.SIG_IGN)), тогда автоматически будет выполняться и ваш дочерний процесс.

Есть два важных оговорки:

  • Вы должны установить обработчик игнорирования, прежде чем запускать дочерний процесс
  • Пользовательские обработчики сигналов reset относятся к обработчикам по умолчанию, так как дочерний процесс не будет иметь доступ к коду обработчика для его запуска.

Итак, если вам нужно настроить свою обработку SIGINT, а не просто игнорировать ее, вы, вероятно, захотите временно игнорировать SIGINT, пока вы запускаете дочерний процесс, а затем (повторно) устанавливаете свой пользовательский обработчик сигнала.

Если вы пытаетесь поймать SIGINT и установить флаг, чтобы вы могли выйти в безопасном месте, а не сразу, помните, что когда вы доберетесь до этой безопасной точки, вашему коду придется вручную очистить своих потомков, так как ваш ребенок процесс и любые запущенные процессы будут игнорировать SIGINT.