python でマルチプロセスの実装方法を調べたので初歩的ですがメモします。多くの記事はプロセス間でのデータの渡し方(shared memory, pipe, queue, etc...)などで、自分が知りたかったことはより基本的なことでした。
やりたかったこと。
- データは共有しない複数の計算を並行して動かしたい
- 結果を書き込むファイルパスは衝突が起きないように実装する
- 終わるまでまつ。
というものです。終了の待ち方のきれいな書き方をまだ習得できてませんが、とりあえず。
使い方
Threading と同じAPIで実装できるようです。
- multipeocessing.Process を利用する
- 関数と関数に渡す引数を設定する。可変長引数はargs、辞書型はkwargs で渡せる。
- start() で開始、join() で終了を待つ
以下のように実装してみました。
from multiprocessing import Process
from time import sleep
from os import getpid, getppid
def f1(name):
""" 引数を渡せる """
print("Hello {} pid={} ppid={} sleep 3 sec".format(name, getpid(), getppid()))
sleep(5)
print("Good morning", name)
def f2(*args, **kwargs):
"""可変長引数、辞書型の引数を渡せる"""
print("args=", args, " kwargs=",kwargs)
print("Hello", kwargs["name"], " pid", getpid(), getppid())
print("Sleeping... {}s".format(kwargs["tlen"]))
sleep(kwargs["tlen"])
print("Good morning", kwargs["name"])
if __name__ == "__main__":
# サブプロセスを作成します
print(__name__, " pid", getpid())
p1 = Process(target=f1, args=("Bob",))
p2 = Process(target=f2, args=("Bob",), kwargs={"name": "Alice", "tlen":10})
# サブプロセスを開始します
p1.start()
p2.start()
print("Processes started.")
# サブプロセスが終了するまで待ちます。
p1.join()
p2.join()
print("Processes joined.")
動作確認
Process で起動したプロセスがmainとは別のプロセス番号になっていること、親プロセスが呼び出し元のプロセス番号になっていることも確認できます。
pid 9576
Hello Bob pid=9577 ppid=9576 sleep 3 sec
Good morning Bob
args= ('Bob',) kwargs= {'name': 'Alice', 'tlen': 10}
Hello Alice pid 9578 9576
Sleeping... 10s
Good morning Alice
Processes started.
Processes joined.
一応、top
の画面で、左端にあるプロセス番号が確かにプロセスが存在していたのを確認できました。
参考
より高度な内容は以下を参照。^^;)
他にもたくさんの記事がありました。
この方法だとjoin でblock されるようなので、どうしたら良いかな。勉強します!!
(2020/04/18)
追記: 2020/04/18
あと仕様書を読むといろいろ書いてあります。terminate()で強制終了、kill signal を送れるとか。
https://docs.python.org/ja/3/library/multiprocessing.html
勢いに乗って続きを書きました。
python multiprocessing の使い方(続き)Pool編