Python のプロセスに引数を渡す

Python のマルチプロセスでは、Process クラスの argskwargs 引数を使って子プロセスにデータを渡します。ただし、プロセス間ではメモリが共有されないため、データの受け渡し方法を理解しておくことが重要です。

位置引数を渡す

args にタプルを指定して、位置引数を渡します。

from multiprocessing import Process

def greet(name, age):
    print(f"Hello, {name}! You are {age} years old.")

if __name__ == "__main__":
    p = Process(target=greet, args=("Alice", 25))
    p.start()
    p.join()

引数が 1 つの場合でも、タプルとして渡す必要があります。args=("Alice",) のようにカンマを忘れないでください。

キーワード引数を渡す

kwargs に辞書を指定して、キーワード引数を渡します。

from multiprocessing import Process

def configure(host, port, debug=False):
    print(f"Server: {host}:{port}, debug={debug}")

if __name__ == "__main__":
    p = Process(
        target=configure,
        args=("localhost", 8080),
        kwargs={"debug": True}
    )
    p.start()
    p.join()

argskwargs を組み合わせて使うこともできます。

オブジェクトを渡す

リストや辞書などのオブジェクトも引数として渡せます。

from multiprocessing import Process

def process_data(data):
    for item in data:
        print(f"Processing: {item}")

if __name__ == "__main__":
    my_list = [1, 2, 3, 4, 5]
    p = Process(target=process_data, args=(my_list,))
    p.start()
    p.join()

渡されたオブジェクトは pickle でシリアライズされてコピーされます。子プロセス内で変更しても、親プロセスのオブジェクトには影響しません。

引数の変更は親プロセスに反映されない

プロセス間ではメモリが独立しているため、子プロセスで引数を変更しても親には反映されません。

from multiprocessing import Process

def modify_list(data):
    data.append(100)
    print(f"Child: {data}")

if __name__ == "__main__":
    my_list = [1, 2, 3]
    p = Process(target=modify_list, args=(my_list,))
    p.start()
    p.join()
    print(f"Parent: {my_list}")  # [1, 2, 3] のまま

親プロセスがリストを渡す

子プロセスにコピーが作られる

子プロセスでコピーを変更

親のリストは変更されない

データを共有したい場合は、QueuePipeValueArrayManager などを使います。

pickle できないオブジェクトに注意

引数は pickle でシリアライズされるため、pickle できないオブジェクトは渡せません。

from multiprocessing import Process

def worker(func):
    func()

if __name__ == "__main__":
    # ラムダ式は pickle できない
    p = Process(target=worker, args=(lambda: print("Hello"),))
    p.start()  # エラーになる
    p.join()

ラムダ式やローカル関数は pickle できないため、代わりにモジュールレベルの関数を定義して使います。

大量のデータを渡す場合

大きなデータを引数で渡すと、シリアライズとコピーのコストがかかります。

ファイルパスを渡して、子プロセス側でファイルを読む
共有メモリ(Value、Array)を使う
Manager でプロキシオブジェクトを使う

大量のデータを効率的に扱いたい場合は、これらの方法を検討してください。