Почему обработчик сигналов Python не запускается? - PullRequest
0 голосов
/ 23 сентября 2018

В приведенном ниже фрагменте кода я зарегистрировал обработчик сигнала с вызовом signal.signal.Однако, хотя процесс завершается по истечении времени ожидания, операторы print или system внутри обработчика не выполняются.Что я делаю неправильно?Я использую Python 2.7.15rc1 в Ubuntu 18.04, 64-разрядная версия.

import signal
import time
import os
import multiprocessing as mp

def handler(signal, frame):
    print "Alarmed"
    os.system('echo Alarmed >> /tmp/log_alarm')

def launch():
    signal.signal(signal.SIGALRM, handler)
    signal.alarm(5)
    print "Process launched"
    os.execv('/bin/cat', ['cat'])
    print "You should not see this"

p = mp.Process(target=launch)
p.start()
print "Process started"
p.join()

1 Ответ

0 голосов
/ 23 сентября 2018

В данный момент вы находитесь за пределами территории Python.os.execv() в конечном итоге привело к выполнению системного вызова execve(2) и в виде его страницы руководства:

Все атрибуты процесса сохраняются во время execve (), кроме следующих:

  • Расположение любых перехваченных сигналов сбрасывается на значение по умолчанию (signal(7)).

...

Что имеет смысл, на самом деле вам не следует запускать какой-то новый код, пока для него зарегистрированы старые обработчики (и не представляете, как это могло бы работать, поскольку обработчики также будут заменены).


Если бы вы реализовали cat -подобное поведение в python и не execve новый процесс, он (более или менее) работал бы так, как вы ожидали:

import signal
import time
import os
import sys
import multiprocessing as mp

def handler(signal, frame):
    print "Alarmed"
    os.system('echo Alarmed >> /tmp/log_alarm')
    sys.exit(0)

def launch():
    signal.signal(signal.SIGALRM, handler)
    signal.alarm(5)
    print "Process launched"
    stdin = os.fdopen(0)
    stdout = os.fdopen(1, 'w')
    line = stdin.readline()
    while line:
        stdout.write(line)
        line = stdin.readline()
    print "You may end here if EOF was reached before being alarmed."

p = mp.Process(target=launch)
p.start()
print "Process started"
p.join()

Примечание:Я просто жестко запрограммировал обработку stdin / stdout в дочернем процессе.И так как вы упомянули Python 2.7, я избегал использования for line in stdin:.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...