Pythonでforkとexecvを試す

Linux のしくみ」と言う本を読んでいて、Pythonで試してみようかなと思い。

https://gihyo.jp/book/2018/978-4-7741-9607-7

fork とか大学の授業でやったな、と懐かしい感じがします。大学生の時にC言語で作ってfork処理が無限ループするとかやらかしてました。ここではPythonforkexecv を試します。

Pythonのバージョンはこちら。

bash-3.2$ python3 --version
Python 3.8.5

スクリプト

作ってみたPythonスクリプトはこちら。

import os
import sys

pid = os.fork()

if pid == 0:
    print('Child process: {}'.format(os.getpid()))
else:
    print('Parent process: {}, Child process: {}'.format(os.getpid(), pid))
    sys.stdout.flush()
    os.execv('/bin/echo', ['/bin/echo', 'Hello'])

fork と execv とは

forkexecv はどちらもプロセスに関する処理をカーネルに対して依頼する関数になります。 fork は現在のプロセスを複製し親プロセスと子プロセスに分けます。 execv は別のプロセスを起動します。

上記のスクリプトではこの二つの処理を使ってプロセスを複製して、親プロセスが別のプロセスを呼び出すようにしてみました。子プロセスか、親プロセスかは戻り値を見て判断します。0なら子プロセス。0以外の値であれば親プロセスでその値は子プロセスのPIDになってます。

親プロセスは execv で別のプロセスを起動します。別のプロセスは元となるプロセスのメモリ上に展開されるので下のプロセスはそこで終了します。

上記のサンプルでは echo コマンドを呼び出しています。 execv の第一引数は実行するプロセスのファイル、第二引数は実行するプロセスに与える引数になります。Pythonの場合、プロセスへの引数はリストを使って渡しますが、その際に一つ目のインデックスにはプロセスを表す名前を渡す慣習らしいです。ここがなぜそんな慣習になっているのかは調べてみてもよくわかりませんでしたが動作に影響を与えていないようです。