在下面的代码片段中,我通过调用signal.signal
注册了信号处理程序。但是,尽管该进程在超时后被终止,但处理程序中的print
或system
语句并未执行。我究竟做错了什么?我在64位Ubuntu 18.04上运行Python 2.7.15rc1。
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()
答案 0 :(得分:1)
您当时不在Python领域。 os.execv()
最终导致进行execve(2)
系统调用,并且其手册页指出:
在execve()期间保留所有进程属性,但 以下:
- 被捕获的任何信号的处理均重置为 默认(
signal(7)
)。...
这确实是有道理的,在注册旧的处理程序时,您真的不希望运行一些新代码(也不知道这怎么可能工作,因为处理程序也会被替换)。
如果您在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进行了硬编码处理。而且,既然您提到了python 2.7,就避免使用for line in stdin:
。