Ctrl-C和SIGINT有什么区别?

时间:2011-12-06 11:02:57

标签: unix sigint keyboardinterrupt

我一直在调试一个Python程序,在收到KeyboardInterrupt异常后会发生段错误。这通常是通过从shell中按 Ctrl + C 来完成的。为了测试特定代码更改是否修复了错误,我有一个小的shell脚本,在启动后随机时间向程序发送SIGINT。我遇到的问题是发送 Ctrl + C 似乎对程序的影响与发送信号SIGINT不同,因此不会导致错误出现,所以我很想知道是什么然后是两种行为之间的区别。

该程序根本不捕获任何键盘操作,它只是一个包含一些线程/进程的python程序。它不安装任何信号处理程序(尽管Python会这样做),stty -a给出intr = ^C。我怀疑可能是 Ctrl + C SIGINT发送到所有子进程/线程,而kill -INT只发送给主进程,但这是我的怀疑去。

以下是发送kill -INT

的shell脚本
wait
while :; do
    seconds="$(python -c 'import random; print random.random()*4')"
    ./mandos --debug --configdir=confdir \
             --statedir=statedir --no-restore --no-dbus &
    pid=$!
    { sleep $seconds; kill -INT $pid; } &
    fg %./mandos
    status=$?
    if [ $status -gt 1 ]; then
        echo "Failed exit $status after $seconds seconds"
        break
    fi
    wait
done

2 个答案:

答案 0 :(得分:17)

^C向前台进程组中的所有进程发送SIGINT。要使用kill执行等效操作,您应该将信号发送到进程组(操作系统级概念):

kill -SIGINT -<pid>

或作业(shell级概念,管道以&结束):

kill -SIGINT %

答案 1 :(得分:4)

作为described here

  

Python默认安装少量信号处理程序:SIGPIPE   被忽略(因此管道和套接字上的写入错误可以报告为   普通的Python异常)和SIGINT被翻译成了一个   KeyboardInterrupt异常。所有这些都可以被覆盖。

所以,发送SIGINT和 Ctrl + c 之间的行为应该相同。

但是,你必须小心KeyboardInterrupt,如果你的代码中某处有一个

try:
   ...
except:   # notice the lack of exception class
   pass

这会“吃掉”KeyboardInterrupt异常。