以下のコードをubuntuで実行します。
import os, time n = os.fork() if n == 0: print("子pid == ", os.getpid()) print("親終了前、getppid() ==", os.getppid()) time.sleep(9) print("親終了後、getppid() ==", os.getppid()) # ★ time.sleep(200000) else: time.sleep(5) print("親終了します.")
本来、親が終了した場合には子はバックグラウンドに移行されると思います。
確かに本コードでも5秒経って親が終了した段階で、bashがフォアに戻り、プロンプトが復帰します。
しかし、★のprint()のように、制御端末に書き込みすると、プロンプトが子プロセスに横取りされ、これはprint()の次のsleep(200000)が終わるまで続きます。
これは、端末に書き込みが生じた場合には、何らかのシグナルが端末ドライバに発せられ、
フォアグランドに移行されているのでしょうか?
それとも、単にバックグラウンドから端末に出力されているだけでしょうか?(これだと子のsleep()の間プロンプトが使えない説明がつかない...)
--追記
TPGIDを見ますと、親終了前は、
bash 21415 21415 21415 3691 21795 pts/2 /usr/bin/python3 loop.py 21795 21415 21795 21415 21795 pts/2 /usr/bin/python3 loop.py 21795 21415 21827 21795 21795 pts/2
親終了後(print()とかした場合も、)は、
bash 21415 21415 21415 3691 21415 pts/2 /usr/bin/python3 loop.py 21795 21415 21827 2188 21415 pts/2
のようにきっちりbashのプロセスグループにフォアが帰っています。
つまり、フォアにはなっていないということがわかりました...
なのに、どうして端末はバックグラウンドであるはずのプロセスのsleep()状態となっているのか、まだここがわかりません。
--追記2
enterを押すことで、制御がbashに戻りました。
これは、あるプロセスをバックグラウンド実行(&)した際に、enter(return)を押すまで制御がシェルに戻らない仕様に関係する(同様のこと)だと思いました。
つまり、親が終了して子はバックに移行したが、その後何らかの標準出力が行われると、一度上と同じ動作になる。(つまり、enterを押すことですぐに制御が戻る....)
回答2件
あなたの回答
tips
プレビュー