Python のプロセスを開始・終了する

Python の Process クラスでは、start() メソッドでプロセスを開始し、join()terminate() で終了を制御します。プロセスのライフサイクルを正しく管理することが、安定した並列処理の鍵になります。

プロセスを開始する

start() メソッドを呼び出すと、新しいプロセスが生成されて実行を開始します。

from multiprocessing import Process

def task():
    print("Task running")

if __name__ == "__main__":
    p = Process(target=task)
    p.start()  # プロセスを開始
    print("Main process continues")
    p.join()

start() は非同期的に動作するため、呼び出し直後に制御がメインプロセスに戻ります。

プロセスの終了を待つ

join() メソッドは、対象のプロセスが終了するまでメインプロセスをブロックします。

from multiprocessing import Process
import time

def slow_task():
    time.sleep(2)
    print("Slow task finished")

if __name__ == "__main__":
    p = Process(target=slow_task)
    p.start()
    p.join()  # プロセスの終了を待つ
    print("Main process finished")

join() を呼ばないと、メインプロセスが先に終了してしまう可能性があります。

タイムアウト付きで待機する

join() にはタイムアウトを指定できます。

from multiprocessing import Process
import time

def long_task():
    time.sleep(10)

if __name__ == "__main__":
    p = Process(target=long_task)
    p.start()
    p.join(timeout=3)  # 最大3秒待つ
    
    if p.is_alive():
        print("Process is still running")
        p.terminate()

タイムアウト後もプロセスが動いている場合は、is_alive() で確認できます。

プロセスを強制終了する

terminate() メソッドでプロセスを強制終了できます。

from multiprocessing import Process
import time

def infinite_task():
    while True:
        time.sleep(1)

if __name__ == "__main__":
    p = Process(target=infinite_task)
    p.start()
    time.sleep(3)
    p.terminate()  # 強制終了
    p.join()
    print("Process terminated")

terminate() は SIGTERM シグナルを送信します。プロセスは直ちに終了するため、クリーンアップ処理は実行されません。

プロセスを即座に強制終了する

Python 3.7 以降では kill() メソッドも使えます。

terminate()

SIGTERM を送信する。プロセスに終了の機会を与える。

kill()

SIGKILL を送信する。即座に強制終了する。

kill() は Unix 系システムで SIGKILL を送信します。どうしても終了しないプロセスに対して使います。

プロセスの状態を確認する

プロセスの状態は is_alive()exitcode で確認できます。

from multiprocessing import Process
import time

def task():
    time.sleep(1)

if __name__ == "__main__":
    p = Process(target=task)
    print(f"Before start: alive={p.is_alive()}, exitcode={p.exitcode}")
    
    p.start()
    print(f"After start: alive={p.is_alive()}, exitcode={p.exitcode}")
    
    p.join()
    print(f"After join: alive={p.is_alive()}, exitcode={p.exitcode}")

exitcode は正常終了なら 0、terminate() で終了した場合は負の値になります。