如何在python中处理不同的信号

时间:2013-12-21 22:22:51

标签: python signals

我在ubuntu上使用python 2.7版本。我很好奇python程序在执行过程中如何处理不同的信号。是否有任何优先选择。?例如:如果同时生成两个不同的信号,将首先提供哪一个?在我下面给出的程序中,它等待用户按下Ctrl-C键,如果这样做,它将显示“进程不能用ctrl-c键杀死!”。除此之外,它每秒都会生成一个SIGALRM信号,并且每秒都会在输出中生成“收到警报”消息。

#!/usr/bin/env python
import signal
import time

def ctrlc_catcher(signum, frm):
    print "Process can't be killed with ctrl-c!"

def alarm_catcher(signum,frame):
    print "Got an alarm"


signal.signal(signal.SIGINT, ctrlc_catcher)
signal.signal(signal.SIGALRM, alarm_catcher)


while True:
  signal.alarm(1)
  time.sleep(1)
  pass

现在,当我执行程序时,它会无限期地产生以下输出:

Got an alarm
Got an alarm
Got an alarm
Got an alarm

如果在执行期间我按下Ctrl-C键一次,则输出被中断,如下所示:

Got an alarm
Got an alarm
Got an alarm
Got an alarm
Process can't be killed with ctrl-c
Got an alarm

一切都按照程序和预期进行。 我的问题是,如果我连续按下ctrl-c键,那么为什么输出如下所示:

Process can't be killed with ctrl-c
Process can't be killed with ctrl-c
Process can't be killed with ctrl-c

为什么在每秒触发警报时,上述输出中是否也显示有关触发警报的输出? 由于signal.SIGNIT,警报信号(signal.ALARM)是否被忽略?或者连续按下Ctrl-C键是暂停的? 感谢

2 个答案:

答案 0 :(得分:3)

您看到的行为是由于两个因素的相互作用:

(1)当您致电signal.alarm时,您清除之前的任何警报;通话结束后,只安排最近请求的闹钟。

(2)捕获的信号终止time.sleep并导致睡眠被缩短;信号处理程序返回后它不会恢复。

现在,当您向进程发送SIGINT时,它通常在休眠期间到达,它会中断,因此在处理程序ctlc_catcher返回后,while循环会立即继续下一次迭代,从该点安排新警报一秒钟并清除任何旧警报。换句话说,如果SIGINT在循环迭代期间到达,那么该迭代几乎永远不会睡眠一整秒,因此循环的下一次迭代将执行并清除已经安排的警报有机会被送到。

由此可见,如果你每秒频繁按cntl-C一次,你根本不会看到"Got an alarm."

如果您想保证每秒发送一次警报,即使有任何中断,您还需要做一些额外的工作来决定是否应该安排警报。

答案 1 :(得分:0)

也许是这样的?

#!/usr/local/cpython-3.3/bin/python

import subprocess

p = subprocess.Popen("./app",
        stdin = subprocess.PIPE,
        stdout = subprocess.PIPE,
        stderr = subprocess.PIPE,
        shell = True)
p.stdin.write(bytes("3\n", "ascii"))
p.stdin.write(bytes("4\n", "ascii"))
print(p.stdout.read())
exit_code = p.wait()
print(exit_code)