web-dev-qa-db-ja.com

Ctrl-CとSIGINTの違いは何ですか?

私はKeyboardInterrupt例外を受け取った後にsegfaultするPythonプログラムをデバッグしています。これは通常、 Ctrl+C シェルから。特定のコード変更でバグが修正されたかどうかをテストするために、起動後にランダムにSIGINTをプログラムに送信する小さなシェルスクリプトを用意しました。私が抱えている問題は、 Ctrl+C シグナルSIGINTを送信する場合とはプログラムの効果が異なるようで、バグが発生することはないため、2つのアクションの違いは何なのかと思います。

プログラムはキーボードアクションをまったくキャッチせず、pythonいくつかのスレッド/プロセスを含むプログラムです。シグナルハンドラーをインストールしません(Python =します)、そしてstty -aintr = ^Cを与えます。 Ctrl+CSIGINTはすべてのサブプロセス/スレッドに送信されますが、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
28
Belorn

^Cは、フォアグラウンドプロセスグループのすべてのプロセスにSIGINTを送信します。 killで同等のことを行うには、プロセスグループに信号を送信する必要があります(OSレベルの概念)。

kill -SIGINT -<pid>

または仕事(シェルレベルの概念、パイプラインは&):

kill -SIGINT %
20
ninjalj

として ここで説明

Pythonはデフォルトで少数のシグナルハンドラーをインストールします:SIGPIPEは無視されます(パイプとソケットの書き込みエラーは通常のPython例外として報告されます)。SIGINTはKeyboardInterrupt例外に変換されます。すべてのこれらは上書きできます。

そのため、SIGINTの送信と Ctrlc

ただし、KeyboardInterruptに注意する必要があります。コードのどこかに

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

これは、KeyboardInterrupt例外を「食べます」。

4
Cédric Julien