Pythonスレッドを取り巻くルールとUnixシグナルの処理方法は何ですか?
KeyboardInterrupt
PythonランタイムによってトリガーされますがSIGINT
、Pythonランタイムによって内部的に処理される、は別の方法で処理されますか?
Pythonスレッドを取り巻くルールとUnixシグナルの処理方法は何ですか?
KeyboardInterrupt
PythonランタイムによってトリガーされますがSIGINT
、Pythonランタイムによって内部的に処理される、は別の方法で処理されますか?
まず、モジュールを使用してシグナルハンドラーを設定する場合signal
は、メインスレッドでシグナルハンドラーを作成する必要があります。別のスレッドで作成しようとすると、例外が発生します。
関数を介して登録されたシグナルハンドラーsignal.signal()
は、常にメインスレッドで呼び出されます。スレッドへのシグナルの送信をサポートするアーキテクチャでは、Cレベルでは、Pythonランタイムはスレッド上のすべてのシグナルを無視し、メインスレッドにシグナルハンドラーがあり、Pythonコードシグナルハンドラーにディスパッチするために使用します。
thread
モジュールのドキュメントには、すべてのUnixシステムで使用できるモジュールがない限り、KeyboardInterrupt
例外(通常はによってトリガーされる)を任意のスレッドに配信SIGINT
できると記載されています。その場合、メインスレッドに配信されます。がないシステムを使用している場合は、スレッドをキャッチして呼び出し、メインスレッドで再レイズする必要があります。signal
signal
KeyboardInterrupt
thread.interrupt_main()
signal
ドキュメントから:
シグナルとスレッドの両方が同じプログラムで使用される場合は、注意が必要です。シグナルとスレッドを同時に使用する際に覚えておくべき基本的なことは、常に実行
signal()
のメインスレッドで操作を実行することです。どのスレッドでも、、、、、または;alarm()
を実行できます。メインスレッドのみが新しいシグナルハンドラーを設定でき、メインスレッドはシグナルを受信する唯一のスレッドになります(これは、基になるスレッドの実装が個々のスレッドへのシグナルの送信をサポートしている場合でも、Pythonシグナルモジュールによって強制されます)。これは、シグナルをスレッド間通信の手段として使用できないことを意味します。代わりにロックを使用してください。getsignal()
pause()
setitimer()
getitimer()