/proc/{PID}/ 配下の情報について Ruby で fork/spawn をした時の違いを確認した時のメモ
(あくまで個人用のメモです)
環境
- OS:amzn2-ami-hvm-2.0.20180810-x86_64-gp2 (ami-08847abae18baa040)
$sudo amazon-linux-extras install ruby
$ ruby --version
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-linux]
/proc{PID} 配下の情報について
以下にまとまった情報あり
- /proc/配下には様々な情報があるが、/proc/{PID} という形式でプロセスが生成されるとディレクトリが作成され、配下にプロセスに関わる情報が格納されている
- {PID} = プロセス ID。プロセスを生成すると生成される ID
- プロセスが終了すると、そのプロセスの /proc/ プロセスディレクトリはなくなる
なお、今回確認したかった cmdline
は以下のように書いてある
cmdline — プロセスを起動した際に発行されたコマンドが格納されています。
fork してみる
fork(2) システムコールを使ってプロセスの複製を作 ります。親プロセスでは子プロセスのプロセスIDを、子プロセスでは nil を返します。ブロックを指定して呼び出した場合には、生成し た子プロセスでブロックを評価します。
内部的には fork(2)のシステムコールを呼び出しているようであり、確認。
上記のサンプルコードを少し修正。
child_pid = fork do
puts "child process. pid: #{Process.pid}"
sleep(1)
end
puts "parent process. pid: #{Process.pid}, child pid: #{child_pid}"
r = `cat /proc/#{child_pid}/cmdline`
puts r
Process.waitpid(child_pid)
実行すると以下のような感じ
$ruby fork.rb
parent process. pid: 2794, child pid: 2795
child process. pid: 2795
rubyfork.rb
/proc/{PID}/cmdline
は rubyfork.rb
となっている。
上記のコードの場合、処理しているのは sleep だが、実行しているのは Ruby のコードという為だと思われる(違ったらご指摘下さい)
spawn してみる
関数 Kernel.#spawn と同じです。
引数を外部コマンドとして実行しますが、生成した 子プロセスの終了を待ち合わせません。生成した子プロセスのプロセスIDを返します。
こっちの場合どうなるのか。
child_pid = spawn({"FOO"=>"BAR", "BAZ"=>nil}, 'sleep 10')
puts "parent process. pid: #{Process.pid}, child pid: #{child_pid}"
r = `cat /proc/#{child_pid}/cmdline`
puts r
Process.waitpid(child_pid)
$ruby spawn.rb
parent process. pid: 2894, child pid: 2895
sleep10
こうなる。
こっちの場合、spawn(env,command)
でよばれて command が cmdline に指定されているという点が違う。
親プロセスID と生成された子プロセスIDが違うのは同じ。
spawn
は Linux のコマンドとして存在する。
一方、 fork はシステムコールという所が違うのだろうか。
TODO
以下辺りの情報など関連する情報を集めてもう少しまとめたい。。。
(fork,spawn,thread...)