#!/usr/bin/python3
import os, sys
ret = os.fork()
if ret == 0:
print("子プロセス:pid={}, 親プロセスのpid={}".format(os.getpid(), os.getppid()))
exit()
elif ret > 0:
print("親プロセス:pid={}, 子プロセスのpid={}".format(os.getpid(), ret))
exit()
sys.exit(1)
root@*******:*******# python3 hello.py
親プロセス:pid=3302, 子プロセスのpid=3303
子プロセス:pid=3303, 親プロセスのpid=3302
os.fork()
子プロセスを forkします。子プロセスでは 0 が返り、親プロセスでは子プロセスの id が返ります
。エラーが発生した場合は、 OSError を送出します。
出典
getpid()
現在のプロセス id を返します。
出典
getppid()
親プロセスのプロセス id を返します
。親プロセスが終了していた場合、Unix では init プロセスの id (1) が返され、Windows では親のプロセス id だったもの (別のプロセスで再利用されているかもしれない) がそのまま返されます。
出典
sys.exit([arg])
Raise a SystemExit exception, signaling an intention to exit the interpreter.
オプション引数 arg には、終了ステータスとして整数 (デフォルトは0)や他の型のオブジェクトを指定することができます。整数を指定した場合、シェル等は 0 は "正常終了"、0 以外の整数を "異常終了" として扱います
。多くのシステムでは、有効な終了ステータスは 0--127 で、これ以外の値を返した場合の動作は未定義です。システムによっては特定の終了コードに個別の意味を持たせている場合がありますが、このような定義は僅かしかありません。Unix プログラムでは構文エラーの場合には 2 を、それ以外のエラーならば 1 を返します
。arg に None を指定した場合は、数値の 0 を指定した場合と同じです。それ以外の型のオブジェクトを指定すると、そのオブジェクトが stderr に出力され、終了コードとして 1 を返します。エラー発生時には sys.exit("エラーメッセージ") と書くと、簡単にプログラムを終了することができます。
出典
気づき
子プロセスでは 0 が返り、親プロセスでは子プロセスの id が返ります
を読むと、二つ値が返っているようだ。
配列のようになっているのだろうか?
なぜ二回処理しているのか? retの値を調べてみる
#!/usr/bin/python3
import os, sys
ret = os.fork()
print(ret)
if ret == 0:
print("子プロセス:pid={}, 親プロセスのpid={}".format(os.getpid(), os.getppid()))
# os.execve("/bin/echo", ["echo", "pid={}からこんにちは".format(os.getpid())], {})
print(ret)
exit()
elif ret > 0:
print("親プロセス:pid={}, 子プロセスのpid={}".format(os.getpid(), ret))
print(ret)
exit()
sys.exit(1)
root@**********:**********# python3 hello.py
3619
親プロセス:pid=3618, 子プロセスのpid=3619
3619
root@**********:**********# 0
子プロセス:pid=3619, 親プロセスのpid=1716
0
気づき
二回やってることがわかった。
本当にプロセスが分身している
execve()関数
#!/usr/bin/python3
import os, sys
ret = os.fork()
if ret == 0:
print("子プロセス:pid={}, 親プロセスのpid={}".format(os.getpid(), os.getppid()))
os.execve("/bin/echo", ["echo", "pid={}からこんにちは".format(os.getpid())], {})
exit()
elif ret > 0:
print("親プロセス:pid={}, 子プロセスのpid={}".format(os.getpid(), ret))
exit()
sys.exit(1)
root@*******:*******# python3 hello.py
親プロセス:pid=3340, 子プロセスのpid=3341
子プロセス:pid=3341, 親プロセスのpid=3340
root@*******:*******# pid=3341からこんにちは
os.execve
これらの関数はすべて、現在のプロセスを置き換える形で新たなプログラムを実行します ; 現在のプロセスは返り値を返しません。 Unix では、新たに実行される実行コードは現在のプロセス内に読み込まれ、呼び出し側と同じプロセス ID を持つ
ことになります。エラーは OSError 例外として報告されます。
出典
さまざまな exec* 関数は、プロセス内にロードされる新しいプログラムに与えるための、引数のリストを取ります。どの関数の場合でも、新しいプログラムに渡されるリストの最初の引数は、ユーザがコマンドラインで入力する引数ではなく、そのプログラム自体の名前
です。 C プログラマならば、プログラムの main() に渡される argv[0] だと考えれば良いでしょう。たとえば、 os.execv('/bin/echo', ['foo', 'bar']) が標準出力に出力するのは bar だけで、 foo は無視
されたかのように見えることになります。
出典