当前位置: 代码迷 >> python >> 为什么 Python 信号处理程序没有被触发?
  详细解决方案

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

热度:83   发布时间:2023-07-14 09:50:02.0

在下面的代码片段中,我通过调用signal.signal注册了信号处理程序。 然而,虽然进程在超时后被终止,处理程序中的printsystem语句并没有被执行。 我究竟做错了什么? 我在 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()

那时您已经超出了 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: