Ctrl-C和SIGINT有什么区别?

Bel*_*orn 27 unix sigint keyboardinterrupt

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

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

这是发送的shell脚本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
Run Code Online (Sandbox Code Playgroud)

nin*_*alj 21

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

kill -SIGINT -<pid>
Run Code Online (Sandbox Code Playgroud)

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

kill -SIGINT %
Run Code Online (Sandbox Code Playgroud)

  • 抱歉是迟钝,但'%'在这种情况下意味着什么? (2认同)

Céd*_*ien 7

如此处所述

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

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

但是,您必须小心使用KeyboardInterrupt,如果您的代码中的某个地方有

try:
   ...
except:   # notice the lack of exception class
   pass
Run Code Online (Sandbox Code Playgroud)

这将“吃掉”KeyboardInterrupt 异常。

  • 我喜欢这个答案,因为它清楚地表明了 SIGINT 和“KeyboardInterrupt”之间的转换到底发生在“哪里”。至于你的警告:出于这个原因,我总是建议使用 `try: ... except Exception: ...` 作为“正常”异常的包罗万象,以免意外捕获诸如 `KeyboardInterrupt` 和`SystemExit`,比较[链接1](https://docs.python.org/3.8/library/exceptions.html#KeyboardInterrupt)和[链接2](https://docs.python.org/3.8/library/异常.html#SystemExit)。 (2认同)