5

私の実験コードは次のようなものです:

import signal

def hi(signum, frame):
    print "hi"

signal.signal(signal.SIGINT, hi)
signal.signal(signal.SIGINT, signal.SIG_IGN)

hiシグナル ハンドラが によってオーバーライドされるため、出力されませんでしたsignal.SIG_IGN

どうすればこれを回避できますか?

4

3 に答える 3

4

ハンドラーが既に存在するかどうかを確認してみてください。その場合は、目的のハンドラーと古いハンドラーを、両方を呼び出すラッパー関数に配置します。

def append_signal(sig, f):

    old = None
    if callable(signal.getsignal(sig)):
        old = signal.getsignal(sig)

    def helper(*args, **kwargs):
        if old is not None:
            old(*args, **kwargs)
        f(*args, **kwargs)

    signal.signal(sig, helper)
于 2012-08-18T12:34:38.943 に答える
2

独自のハンドラーをオーバーライドしたくない場合は、ハンドラーが設定されているかどうかを確認してください。

if signal.getsignal(signal.SIGINT) in [signal.SIG_IGN, signal.SIG_DFL]:
    signal.signal(signal.SIGINT, hi)

ドキュメントによると、上位のプロセスがすでにデフォルトからハンドラーを再割り当てしている可能性があります。それをオーバーライドしたくない場合はNone、シグナルのリストに追加します。

の明らかなラッパーsignal.signal(..., signal.SIG_IGN)not inテストです。

コメントに応じて追加

シグナルは非常に粒状であるため、シグナルハンドラの連鎖はあまり行われません。本当にこれをやりたいのであれば、atexitのモデルに従い、ハンドラーによって呼び出される関数を登録します。

于 2012-08-18T11:47:07.140 に答える
0

C で行う場合と同じように行うだけです。

sig_hand_prev = None

def signal_handler(signum, frame):
  ...
  signal.signal(signum, sig_hand_prev)
  os.kill(os.getpid(), signum)

def install_handler(signum):
  global sig_hand_prev
  sig_hand_prev = signal.signal(signum, signal_handler)

ここでの重要なアイデアは、前のハンドラーのみを保存し、作業が終了したときに再び発生させることです。このように、シグナル処理は単一のリンクされたリスト OOB です。

于 2019-11-14T10:31:20.993 に答える