我在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键是暂停的? 感谢
答案 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)