我在 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.ALARM)是否因为signal.SIGNIT而被忽略?或者连续按下 Ctrl-C 键会暂停某些内容? 谢谢
最佳答案
您看到的行为是由于两个因素的相互作用造成的:
(1) 当您调用signal.alarm
时,您清除了之前的所有警报;调用后,仅安排最近请求的警报。
(2) 捕获的信号终止 time.sleep
并导致 sleep 缩短;信号处理程序返回后它不会恢复。
现在,当您向进程发送 SIGINT
时,它通常在 sleep 期间到达,并会中断 sleep ,因此在处理程序 ctlc_catcher
返回 while
循环立即继续下一次迭代,从该点开始安排新警报一秒钟并清除所有旧警报。换句话说,如果在循环迭代期间 SIGINT 到达,则该迭代几乎永远不会休眠一整秒,因此循环的下一次迭代将执行并清除已安排的警报在它有机会交付之前。
由此可见,如果您按 cntl-C 的频率超过每秒一次,您根本不会看到“有警报。”
。
如果您想保证在任何中断的情况下每秒发送一次警报,则必须做一些额外的工作来决定在每次循环迭代时是否应该安排警报。
关于python - python中如何处理不同的信号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20724157/