Pythonでシグナルを捕捉
この記事では、Pythonでシグナルを捕捉し処理する方法について説明します。signalモジュールを使用して、割り込みシグナル(SIGINT, SIGTERMなど)を検出し、適切なクリーンアップ処理を行う方法を学びます。
目次
signalモジュールの概要
Pythonのsignalモジュールは、プログラムがシグナルを受信した際に、特定の関数を呼び出すための機能を提供します。シグナルとは、オペレーティングシステムからプログラムに送られるイベントで、キーボード割り込み(Ctrl+C)やプログラムの強制終了などに対応します。
このモジュールを使うことで、プログラムが予期せぬ終了をしたり、リソースリークを起こしたりすることを防ぎ、安全に終了処理を行うことができます。
シグナルハンドラの登録
signal.signal()関数を使用して、特定のシグナルに対するハンドラ関数を登録します。
import signal
import time
def handler(signum, frame):
print('Signal handler called with signal', signum)
# クリーンアップ処理など
signal.signal(signal.SIGINT, handler)
第一引数にシグナルの種類、第二引数にハンドラ関数(関数オブジェクト)を指定します。
シグナルハンドラの作成
シグナルハンドラは、シグナルが受信された際に実行される関数です。この関数では、プログラムの状態を保存したり、開いているファイルを閉じたり、ネットワーク接続を切断したりするなどのクリーンアップ処理を行うことができます。
def handler(signum, frame):
print('Signal received:', signum)
# 終了処理など
print('Cleaning up...')
exit(0)
ハンドラ関数は、シグナル番号とスタックフレーム(frame)を引数として受け取ります。通常は、クリーンアップ処理を実装し、その後プログラムを終了します。
シグナルの種類と意味
いくつかの一般的なシグナルとそれらの意味を以下に示します。
- SIGINT: キーボード割り込み(Ctrl+C)
- SIGTERM: プログラムの終了要求
- SIGKILL: プログラムの強制終了(ハンドラで捕捉できない)
- SIGHUP: セッションの終了
よくあるエラーと対処法
シグナル処理におけるよくあるエラーとその対処法
- ハンドラ関数の登録に失敗した場合: signal.signal()関数の戻り値をチェックする
- ハンドラ関数内で例外が発生した場合: try-exceptブロックで例外を捕捉する
- シグナルが正しく処理されない場合: シグナルの種類、ハンドラの登録方法を確認する
実践例:割り込み時の処理
簡単な例として、Ctrl+Cによる割り込みを処理するプログラムを示します。
import signal
import time
def handler(signum, frame):
print('Ctrl+C が押されました。終了します。')
exit(0)
signal.signal(signal.SIGINT, handler)
print('プログラムが実行中です...')
while True:
time.sleep(1)