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

2024-04-28 07:30:05 发布

您现在位置:Python中文网/ 问答频道 /正文

我在ubuntu上使用python2.7版本。我很好奇python程序在执行期间如何处理不同的信号。是否有基于优先级的选择。?例如:如果在同一时间产生两个不同的信号,哪一个将首先被服务?在下面给出的程序中,它等待用户按Ctrl-C键,如果这样做,它将显示“进程不能用Ctrl-C键终止!”。与此同时,它每秒钟都会生成一个SIGALRM信号,并且每秒钟都会在输出中生成“Got an alarm”消息。在

#!/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

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

^{pr2}$

如果在执行过程中我按了一次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

为什么报警触发的输出不也出现在上面的输出中,因为报警是每秒触发的? 是报警信号吗(信号报警)被忽视是因为信号符号?或者连续按Ctrl-C键是在暂停什么? 谢谢


Tags: 程序an报警signal信号withbeprocess
2条回答

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

(1)当您调用signal.alarm时,您将清除所有以前的报警;在调用之后,只会安排最近请求的报警。在

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

现在,当您向您的进程发送SIGINT时,它通常在睡眠期间到达,它会中断,因此在处理程序ctlc_catcher返回{}循环后,立即继续到下一个迭代,从该点调度一秒的新警报并清除所有旧警报。换句话说,如果SIGINT在循环的一次迭代期间到达,那么这个迭代几乎永远不会以一秒钟的睡眠结束,因此循环的下一次迭代将执行并在有机会传递之前清除已经计划好的警报。在

由此可知,如果您按cntl-C的频率超过每秒一次,则根本看不到"Got an alarm."。在

如果您想保证在任何中断的情况下每秒发送一次警报,那么您必须做一些额外的工作,以决定在每次循环迭代中是否应该安排警报。在

也许是这样的?在

#!/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)

相关问题 更多 >