问题描述
在下面的代码片段中,我通过调用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()
1楼
那时您已经超出了 Python 领域。
os.execv()
最终导致执行系统调用,正如其手册页所述:
在 execve() 期间保留所有进程属性,但以下情况除外:
- 被捕获的任何信号的处置都被重置为默认值( )。
...
这确实有道理,您不应该在注册旧处理程序的同时运行一些新代码(并且不知道如何工作,因为处理程序也将被替换)。
如果您实施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:
使用for line in stdin:
。