41

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

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

这是发送kill -INT.

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
4

2 回答 2

35

^CSIGINT向前台进程组中的所有进程发送一个。要对 进行等效操作kill,您应该将信号发送到进程组(操作系统级别的概念):

kill -SIGINT -<pid>

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

kill -SIGINT %
于 2011-12-06T20:30:45.823 回答
8

如此处所述

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

Ctrl因此,发送 SIGINT 和+之间的行为应该相同c

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

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

这将“吃掉” KeyboardInterrupt 异常。

于 2011-12-06T11:16:56.390 回答