2009-11-02 9 views
7

何らかの理由で、siginterrupt()は最初に受信した信号の振る舞いを設定しているようです。siginterrupt()は最初のシグナルに対してのみ機能しますか? (Python)

このサンプルプログラムでは、最初のSIGQUITは何もしないように見えますが、2番目のsigquitは "SIGQUIT Handler"を出力し、s.accept()は中断システムコール例外をスローします。

from signal import * 
from socket import * 
import sys 

def sigquitHandler(signum, frame): 
     print("SIGQUIT Handler") 

s = socket() 
s.bind(("0.0.0.0", int(sys.argv[1]))) 
s.listen(5) 

signal(SIGQUIT, sigquitHandler) 
siginterrupt(SIGQUIT, False) 

client, addr = s.accept() # Or any syscall that blocks 
client.close() 
s.close() 

私はここで誤解していますか?


編集:ここではわかりませんが、このプログラムでは、SIGQUITがselect()を中断します。それは起こるはずですか?

from signal import * 
import select 
import sys 

def sigquitHandler(signum, frame): 
    print("SIGQUIT Handler") 

signal(SIGQUIT, sigquitHandler) 
siginterrupt(SIGQUIT, False) 

select.select([sys.stdin], [], []) 
+1

を参照してください。私は 'select'のようなシステムコールには当てはまらないと思います。 – mhawke

+0

ああ、大丈夫です。もう一度ありがとう:) –

答えて

2

どれがunixですか? Cレベルでは、BSD vs System 5(SYSV)でのシグナル処理の実装とセマンティクスが異なります。

私の推測では、SYSVを使用していると思います。この場合、シグナルハンドラが返された後(古典的なシグナルハンドリング)、シグナルの配置はSIG_DFLにリセットされます。 SYSVでハンドラを再インストールするには、ハンドラ内でsignalを呼び出す必要があります。

多かれ少なかれ、BSDスタイルのシグナル処理を提供します。したがって、SYSV OSでは、Pythonはsignalを介してシグナルハンドラの再インストールを管理している必要があります。さて、siginterrupt用のPython DOCOに従って:

注)(シグナルとシグナルハンドラ をインストールするための 真のフラグ値で)( 暗黙的に呼び出すことsiginterruptにより中断に再起動 動作をリセットすること与えられた信号は です。

そして、そこには、あなたが行く - Pythonは自動的に(意味論のようなBSDを提供するために)あなたのシグナルハンドラを再インストールされ、それがうまく暗黙的siginterrupt(1)を呼び出す方法でそうすることができる場合。

もちろん、私の推測は間違っている可能性があります。

あなた

このようsigquitHandlerを定義することによってこの問題を解決することができるかもしれない:それはPythonが信号配置を復元したときにどのように依存

def sigquitHandler(signum, frame): 
    print("SIGQUIT Handler") 
    siginterrupt(SIGQUIT, False) 

EDIT

無影響したシグナルハンドラにsiginterrupt(SIGQUIT, False)を追加します。

EDIT 2

した後、いくつかのより多くの、これは単なるSYSVの問題ではありません、それは明確なことのpython2.6ソースコードでチャンスをうかがっ。それはBSDシステムにも影響します。

+0

それは感謝します、ありがとう! –

4

pythonのbugです。"シグナルが受信されるとflag = Falseでsiginterruptがリセットされます"は、後のpython2.6で修正されました。 (2.6.6+、2.7+)

2番目の場合、siginterruptはselect()に影響しません。

は、私は `siginterrupt`は本当に唯一のデータの転送(例えば、オープンなどのプリミティブ、読み取りまたは書き込み)を伴うシステムコールに適用されると思いますhttp://lkml.org/lkml/2005/7/23/119

関連する問題