7.1 組み込みモジュール signal
このモジュールはパイソンでシグナルハンドラを使うための仕組みを提供します。
シグナルハンドラを使う場合一般的なルールがいくつかあります。
-
特定のシグナルに対するハンドラは一度セットされると明示的にリセットされるまで残ります。(すなわちパイソンはベースシステムの実装にかかわらずBSDスタイルのインタフェースをエミュレートします。)ただし、SIGCHLDに対するハンドラは例外でベースシステムの実装に従います。
-
クリティカルセクションから一時的にシグナルを「ブロックする」方法はありません。(これはすべてのUnixの種類でサポートされていないからです。)
-
パイソンのシグナルハンドラはユーザから見る限り非同期に呼び出されますが、パイソンインタプリタの「これ以上分けられない微小な」命令の間においてのみ発生します。
これはC言語で実装された長い計算(例えば大きなテキストに対する正規表現のマッチング)の間に到着したシグナルは任意の時間だけ遅延する可能性があることを意味しています。
-
I/O操作の間にシグナルが到着すると、シグナルハンドラがリターンしたあとI/O操作は例外を発生させる可能性があります。これはベースとなるUnixシステムの割り込みシステムコールに関する語義に依存します。
-
C言語のシグナルハンドラは常にリターンするので、SIGFPEまたはSIGSEGVのような同期エラーを捕まえることはほとんど意味がありません。
-
パイソンはデフォルトでいくつかのシグナルハンドラをインストールします。
SIGPIPEは無視されます(パイプとソケットへの書き込みエラーは通常のパイソンの例外として報告できるからです)。
SIGINTはKeyboardInterrupt例外に翻訳されます。
SIGTERMは実際に終了する前に必要なクリーンアップ(特にsys.exitfunc)が実行されるようにキャッチされます。これらはすべてオーバライドできます。
-
シグナルとスレッドが同じプログラムで使われている時は注意が必要です。
シグナルとスレッドを同時に使う際に覚えておく基本的なことは、常に実行のメインスレッドでsignal()操作を実行することです。
どのスレッドもalarm(), getsignal(), または pause()を実行することが可能です。一方メインスレッドのみで新しいシグナルハンドラをセットでき、メインスレッドのみがシグナルを受け取ります(これは、ベースシステムのスレッドの実装が個別スレッドにシグナルを送ることをサポートしていたとしてもパイソンのsignalモジュールによって強制されています)。これはシグナルをスレッド間通信の手段として使うことができないことを意味しています。そのかわりlockを使って下さい。
signalモジュールで定義されている変数:
- SIG_DFL
-
これは2つの標準シグナル処理オプションのうちの1つで、シグナルに対するデフォルト関数を単純に実行します。例えば、多くのシステムではSIGQUITに対するデフォルトアクションはコアを吐いて終了することです。一方SIGCLDに対するデフォルトアクションはそれを無視することです。
- SIG_IGN
-
これはもう一方の標準シグナルハンドラで、単純に与えられたシグナルを無視します。
- SIG*
-
すべてのシグナル番号は記号的に定義されています。例えば、ハングアップシグナルはsignal.SIGHUPとして定義されています。変数名はCプログラムで使われていて、"<signal.h>"にある名前と同じです。Unixの`signal()'に関するmanページに存在するシグナルの一覧があります(あるシステムではsignal(2)に、また別のシステムではsignal(7)に一覧があります)。
すべてのシステムが同じシグナル名の組を定義しているわけではなく、システムで定義されているシグナル名のみがこのモジュールで定義されていることに注意して下さい。
- NSIG
-
最も高いシグナル番号より1大きい数。
signalモジュールは以下の関数を定義しています。
- alarm (time)
-
timeが0でなければ、この関数はtime秒でそのプロセスにSIGALRMシグナルが送られることを要求します。
過去にスケジュールされたどのアラームもキャンセルされます(つまりいつでも1つのアラームのみがスケジュール可能です)。
戻り値は、過去セットされたアラームが上がるまでの残り秒数です。
timeが0のときはアラームはスケジュールされず、スケジュールされていたアラームはキャンセルされません。戻り値は過去にスケジュールされたアラームまでに残っている秒数です。戻り値が0のときは現在スケジュールされているアラームはありません。(Unixのmanページalarm(2)を参照)
- getsignal (signalnum)
-
シグナルsignalnumに対する現在のシグナルハンドラを返します。
戻り値は呼び出し可能なパイソンオブジェクト、または特別な値signal.SIG_IGN、 signal.SIG_DFL、 Noneのうちの1つです。
ここでsignal.SIG_IGNはそのシグナルが過去に無視されたことを意味し、
signal.SIG_DFLはそのシグナルのデフォルト処理が過去に使用されたことを意味し、Noneは以前のシグナルハンドラはパイソンからインストールされていないことを意味しています。
- pause ()
-
シグナルを受け取るまでそのプロセスをスリープさせます。適切なハンドラがその後呼び出されます。戻り値はありません。(Unixのmanページsignal(2)を参照)
- signal (signalnum, handler)
-
シグナルsignalnumに対するハンドラを関数handlerにセットする。
handlerは呼び出し可能なパイソンオブジェクト、または特別な値signal.SIG_IGNまたはsignal.SIG_DFLを指定できます。
以前のシグナルハンドラが戻されます(上記getsignal()の説明を参照)。
(Unixのmanページsignal(2)を参照)
スレッドが有効な場合はこの関数はメインスレッドからのみ呼び出すことができます。
他のスレッドから呼び出そうとするとValueError例外が発生します。
handlerは2つの引数で呼ばれます。シグナル番号と現在のスタックフレーム(Noneまたはframeオブジェクト:frameオブジェクトの説明はリファレンスマニュアルを参照)です。
guido@python.org