为什么Python信号处理程序没有被触发?

为什么Python信号处理程序没有被触发?,python,python-2.7,signals,Python,Python 2.7,Signals,在下面的代码片段中,我通过调用signal.signal注册了信号处理程序。但是,尽管进程在超时后被终止,但处理程序中的print或system语句不会被执行。我做错了什么?我正在Ubuntu 18.04上运行Python2.7.15rc1,64位 import signal import time import os import multiprocessing as mp def handler(signal, frame): print "Alarmed" os.syst

在下面的代码片段中,我通过调用
signal.signal
注册了信号处理程序。但是,尽管进程在超时后被终止,但处理程序中的
print
system
语句不会被执行。我做错了什么?我正在Ubuntu 18.04上运行Python2.7.15rc1,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()

你就在Python领域之外的那一点上
os.execv()
最终导致进行系统调用,如手册页所述:

在execve()期间,除 以下:

  • 捕捉到的任何信号的处理将重置为 默认值为()

这是有道理的,您不应该真的希望在注册旧处理程序的同时运行一些新代码(因为处理程序也会被替换,所以不知道该如何工作)


如果您在python中实现了类似于
cat
的行为,并且没有
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的处理。既然您提到了Python2.7,我就避免在stdin:

中对行使用
,有许多系统调用不应该从信号处理程序调用。
system
libc函数可以进行多种操作,例如派生一个新进程。您可以编写一个小Python来直接执行相同的操作。