Pythonで`signal`モジュールを使ってプロセス間通信を実現する方法

この記事では、Pythonの`signal`モジュールを使ってプロセス間通信(IPC)をどのように行うかを詳細に解説します。具体的なコード例、その詳細解説、および応用例を2つ含めています。これにより、プロセス間でシグナルを送信して通信を実現する方法について理解を深めることができます。

目次

signalモジュールとは?

Pythonの`signal`モジュールは、UNIXシグナルを扱うためのライブラリです。シグナルは、プロセス間通信(IPC)やプロセスの終了などを制御するための仕組みで、`signal`モジュールを使うことで、Pythonプログラム内でこれらのシグナルを扱うことができます。

シグナルの基礎

シグナルは短い通知メッセージであり、プロセスに対して何らかの操作(割り込み、終了など)を行うように指示します。UNIX系のオペレーティングシステムでは、多くの種類のシグナルが存在します。例えば、`SIGINT`は割り込みシグナルであり、通常はCtrl+Cを押すことで送信されます。

import signal

# SIGINT(割り込みシグナル)を処理する関数
def handle_sigint(signum, frame):
    print("SIGINTを受信しました。プログラムを終了します。")
    exit(0)

# SIGINTに対するハンドラを設定
signal.signal(signal.SIGINT, handle_sigint)

print("プログラムが実行中です。Ctrl+Cで終了します。")
while True:
    pass

このコードでは、`signal`モジュールを使って、SIGINT(割り込みシグナル)を受信したときにプログラムを終了するように設定しています。

信号の送信と受信

プロセス間で信号を送受信する基本的な方法を解説します。

信号の送信

Pythonで信号を送信するには、`os.kill`関数を使用します。第一引数にはプロセスID、第二引数には送信するシグナルを指定します。

import os
import signal

# 現在のプロセスIDを取得
pid = os.getpid()

# SIGUSR1シグナルを送信
os.kill(pid, signal.SIGUSR1)

信号の受信とハンドリング

信号を受信するには、`signal.signal()`関数を使用して、対応するシグナルハンドラを設定します。

import signal

def handle_sigusr1(signum, frame):
    print("SIGUSR1を受信しました")

signal.signal(signal.SIGUSR1, handle_sigusr1)

応用例1:タイムアウト処理

`signal`モジュールを使って、一定時間後にプロセスを終了するタイムアウト処理を実装する方法です。

import signal
import time

def timeout_handler(signum, frame):
    print("タイムアウトです。プログラムを終了します。")
    exit(0)

# SIGALRMに対するハンドラを設定
signal.signal(signal.SIGALRM, timeout_handler)

# 5秒後にSIGALRMを発生させる
signal.alarm(5)

print("処理を開始します。5秒以内に終わらなければタイムアウトします。")
time.sleep(10)

応用例2:プロセスの一時停止と再開

SIGSTOPとSIGCONTシグナルを使用して、プロセスの一時停止と再開を制御します。

import os
import signal
import time

pid = os.getpid()

def resume_process(signum, frame):
    print("プロセスが再開されました")

# SIGCONTに対するハンドラを設定
signal.signal(signal.SIGCONT, resume_process)

print("プロセスを一時停止します")
os.kill(pid, signal.SIGSTOP)

print("処理を再開します")
time.sleep(2)

まとめ

Pythonの`signal`モジュールを使うことで、プロセス間での信号通信が容易になります。具体的な応用例を通して、より実践的な使い方を理解できたことでしょう。

コメント

コメントする

目次