ここではUNIXをベースとしたオペレーティング・システム上でのプロセスベースの並列処理のプログラミングを前提として考えます。
PytyonではUNIXのシステムコール fork()を直接的にコントロールするよりも便利なProcessクラスが用意されています。
今回紹介しているサンプルコードはLinux version 5.13.0で動作を確認しています。
サンプルコードprocsample.pyは子プロセスを生成するプログラムです。子プロセスとしてフォークするのはユーザが定義した関数child_process()です。親プロセスの中で関数Process()を使って子プロセスを生成します。生成されたインスタンスである変数pをメソッドstart()を使って子プロセスをスタートさせ、そのインスタンスをリストprocess_queueに保持しておきます。
UNIXにおいて子プロセスが終了した際には親プロセスでの事後処理が必要になります。このプログラムの中では、その処理がp.join()になります。ここでのポイントは、生成させたプロセスのインスタンスがリストprocess_queueに貯められていることです。子プロセスは非同期に動作していますが、終了はリストの最初から順に進めている点です。子プロセスのプログラムの終了タイミングが前後した場合でも、終了した順に処理するのではなく、process_queueに収められた順番に処理されます。
# File: datatype.py
# 子プロセスを生成する
#
import sys
import os
import time
from multiprocessing import Process
#子プロセス
def child_process(msg):
time.sleep(3) # 3秒まってから処理開始
print(msg,os.getpid()) # 子プロセスのpid
for t in range(5):
time.sleep(1) # 1秒の待ち
print(msg+':'+str(t)) # 何のプロセスが何回目かを出力
sys.exit(0) # 子プロセス終了
if __name__ == '__main__':
process_queue=[] # 子プロセスを保持しておくため
for msg in [ 'A','B','C','D','E']:
p = Process(target=child_process, args=(msg,)) # プロセスを生成
p.start() # プロセススタート
process_queue.append(p) # キューにつめる
print("***Waiting Join Child Process***")
for p in process_queue: # 子プロセスの終了時の後処理
p.join() # 子プロセス終了までブロッキングされる
print(p)