Ctrl-C 和 SIGINT 有什么区别?

发布于 2024-12-19 21:39:28 字数 1020 浏览 2 评论 0原文

我一直在调试一个 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

I have been debugging a Python program which segfaults after receiving a KeyboardInterrupt exception. This is normally done by pressing Ctrl+C from the shell. To test if a particular code change fixed the bug, I had a small shell-script that sent SIGINT to the program at random time after start-up. The problem I have is that sending Ctrl+C seems to have a different effect on the program than sending the signal SIGINT and is thus not causing the bug to appear, so I quite wonder what the difference is then between the two actions.

The program does not catch any keyboard actions at all, and is just a python program with some threads/processes in them. It installs no signal handlers (though Python does), and stty -a gives intr = ^C. I suspect it might be that Ctrl+C sends SIGINT to all the sub-processes/threads while kill -INT only sends to the primary process, but that is as far my suspicions go.

Here is the shell script which sends the 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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

泪痕残 2024-12-26 21:39:28

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

kill -SIGINT -<pid>

或发送到作业(shell 级别概念,管道以 &< /代码>):

kill -SIGINT %

^C sends a SIGINT to all the processes in the foreground process group. To do the equivalent with kill, you should send the signal to the process group (OS-level concept):

kill -SIGINT -<pid>

or to the job (shell-level concept, the pipeline ended with &):

kill -SIGINT %
北方的巷 2024-12-26 21:39:28

正如此处所述

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

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

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

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

this 将会“吃掉”KeyboardInterrupt 异常。

As described here :

Python installs a small number of signal handlers by default: SIGPIPE
is ignored (so write errors on pipes and sockets can be reported as
ordinary Python exceptions) and SIGINT is translated into a
KeyboardInterrupt exception. All of these can be overridden.

so, the behaviour should be the same between sending a SIGINT and a Ctrl + c.

But, you have to be carefull with the KeyboardInterrupt, if somewhere in your code you've got a

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

this will "eat" the KeyboardInterrupt exception.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文