Pythonでsignalモジュールを使って実行中のコードを中断・インタラプトする方法

この記事では、Pythonで`signal`モジュールを用いた実行中のコードの中断とインタラプトについて詳しく解説します。具体的なコード例とその詳細な解説、さらに応用例を2つ以上含めています。

目次

signalモジュールとは

`signal`モジュールは、Unixシグナルのような非同期のイベントをPythonプログラム内で取り扱うための標準ライブラリです。これを使うことで、特定のシグナルを受け取った際に特定の処理を実行することができます。

基本的な使い方

まずは、`signal`モジュールの基本的な使い方から見ていきましょう。

import signal
import time

# シグナルハンドラ関数
def handler(signum, frame):
    print(f"シグナル{signum}を受信しました。")

# SIGINT (Ctrl + C) を受け取ったときにhandler関数を呼び出す
signal.signal(signal.SIGINT, handler)

# この後の処理
print("プログラムが始まります。Ctrl+Cで終了します。")
while True:
    time.sleep(1)

このコードでは、`SIGINT`(通常はCtrl+Cから送信される)を受け取った際に`handler`関数が呼び出されるように設定しています。

signalモジュールの主要な関数と定数

– `signal.signal()`: シグナルハンドラを設定
– `signal.alarm()`: アラームシグナルを設定
– `signal.SIGINT`, `signal.SIGTERM` など: 各種シグナル定数

実行中のコードを安全に中断する

次に、`signal`モジュールを用いて、実行中のコードを安全に中断する方法を解説します。

タイムアウト処理の例

import signal

# タイムアウトの時間(秒)
TIMEOUT = 5

# タイムアウト時に呼ばれるハンドラ関数
def timeout_handler(signum, frame):
    raise TimeoutError("処理がタイムアウトしました")

# アラームシグナルとハンドラを設定
signal.signal(signal.SIGALRM, timeout_handler)

# アラーム(タイマー)を設定
signal.alarm(TIMEOUT)

try:
    # タイムアウトするまでの処理
    # ...
except TimeoutError as te:
    print(te)

この例では、`SIGALRM`を用いて一定時間後に処理を中断するタイムアウトを実装しています。

応用例

複数のシグナルをハンドリングする

# SIGINTとSIGTERMを同じハンドラで処理
signal.signal(signal.SIGINT, handler)
signal.signal(signal.SIGTERM, handler)

このように、複数のシグナルを同じハンドラで処理することも可能です。

動的にハンドラを変更する

# 状況に応じてハンドラを変更
def another_handler(signum, frame):
    print("別のハンドラです")

signal.signal(signal.SIGINT, another_handler)

実行中に`signal.signal()`を再度呼び出すことで、動的にハンドラを変更することができます。

まとめ

`signal`モジュールは、Pythonで非同期のイベントを簡単かつ効率的に扱うための強力なツールです。特定のシグナルがプログラムに送信されたときに、任意のコードを実行できます。この機能を使って、より堅牢で柔軟なプログラムを作成することができるでしょう。

コメント

コメントする

目次