なるほどUNIXプロセス

tatsu-zine.com

以前半額セールの時に買って積本にしてた。第11章まで。 今のところはわかりやすくてとても良い。

第1章 はじめに

第2章 本書の手引き

第3章 プロセスにはIDがある

[1] pry(main)> puts Process.pid
47940
=> nil
% ps -p 47997
  PID TTY           TIME CMD
47997 ttys002    0:00.27 pry

第4章 プロセスには親がいる

[1] pry(main)> puts Process.pid
48076
=> nil
[2] pry(main)> puts Process.ppid
47871
=> nil
% ps -p 47871
  PID TTY           TIME CMD
47871 ttys002    0:00.18 -zsh

第5章 プロセスにはファイルディスクリプタがある

[1] pry(main)> passwd = File.open("/etc/passwd")
=> #<File:/etc/passwd>
[2] pry(main)> puts passwd.fileno
8
=> nil
[3] pry(main)> hosts = File.open("/etc/hosts")
=> #<File:/etc/hosts>
[4] pry(main)> puts hosts.fileno
9
=> nil
[5] pry(main)> passwd.close
=> nil
[6] pry(main)> null = File.open("/dev/null")
=> #<File:/dev/null>
[7] pry(main)> puts null.fileno
8
=> nil
[1] pry(main)> passwd = File.open("/etc/passwd")
=> #<File:/etc/passwd>
[2] pry(main)> puts passwd.fileno
8
=> nil
[3] pry(main)> passwd.close
=> nil
[4] pry(main)> puts passwd.fileno
IOError: closed stream
from (pry):4:in `fileno'
[1] pry(main)> puts STDIN.fileno
0
=> nil
[2] pry(main)> puts STDOUT.fileno
1
=> nil
[3] pry(main)> puts STDERR.fileno
2
=> nil

第6章 プロセスにはリソースの制限がある

[1] pry(main)> p Process.getrlimit(:NOFILE)
[256, 9223372036854775807]
=> [256, 9223372036854775807]
[1] pry(main)> Process.setrlimit(:NOFILE, 4096)
=> nil
[2] pry(main)> p Process.getrlimit(:NOFILE)
[4096, 4096]
=> [4096, 4096]
[1] pry(main)> Process.setrlimit(:NOFILE, Process.getrlimit(:NOFILE)[1])
Errno::EINVAL: Invalid argument - setrlimit
from (pry):1:in `setrlimit'
[1] pry(main)> Process.setrlimit(:NOFILE, 8)
=> nil
[2] pry(main)> File.open("/dev/null")
Errno::EMFILE: Too many open files @ rb_sysopen - /dev/null
from (pry):2:in `initialize'
[1] pry(main)> Process.getrlimit(:NPROC)
=> [709, 1064]
[2] pry(main)> Process.getrlimit(:FSIZE)
=> [9223372036854775807, 9223372036854775807]
[3] pry(main)> Process.getrlimit(:STACK)
=> [8388608, 67104768]

第7章 プロセスには環境がある

% MESSAGE="wing it" ruby -e "puts ENV['MESSAGE']"
wing it
[1] pry(main)> ENV["MESSAGE"] = "wing it"
=> "wing it"
[2] pry(main)> system "echo $MESSAGE"
wing it
=> true
[1] pry(main)> puts ENV["EDITOR"]

=> nil
[2] pry(main)> puts ENV.has_key?("PATH")
true
=> nil
[3] pry(main)> ENV.is_a?(Hash)
=> false

第8章 プロセスには引数がある

% cat argv.rb
p ARGV
% ruby argv.rb foo bar -va
["foo", "bar", "-va"]

第9章 プロセスには名前がある

[1] pry(main)> puts $PROGRAM_NAME
pry
=> nil
[2] pry(main)> 10.downto(1) do |num|
[2] pry(main)*   $PROGRAM_NAME = "Process: #{num}"
[2] pry(main)*   puts $PROGRAM_NAME
[2] pry(main)* end
Process: 10
Process: 9
Process: 8
Process: 7
Process: 6
Process: 5
Process: 4
Process: 3
Process: 2
Process: 1
=> 10

第10章 プロセスには終了コードがある

[1] pry(main)> at_exit { puts "Last!" }
=> #<Proc:0x007fd744805200@(pry):1>
[2] pry(main)> exit
Last!
[1] pry(main)> at_exit { puts "Silence" }
=> #<Proc:0x007ff3aa36d7b0@(pry):1>
[2] pry(main)> exit!
[1] pry(main)> abort "Something went horribly wrong."
Something went horribly wrong.
[1] pry(main)> at_exit { puts "Last!" }
=> #<Proc:0x007fc04aaf4c88@(pry):1>
[2] pry(main)> abort "Something went horribly wrong."
Something went horribly wrong.
Last!
[1] pry(main)> raise 'hell'
RuntimeError: hell
from (pry):1:in `__pry__'

第11章 プロセスは子プロセスを作れる

[1] pry(main)> if fork
[1] pry(main)*   puts "entered the if block"
[1] pry(main)* else
[1] pry(main)*   puts "entered the else block"
[1] pry(main)* end
entered the if block
entered the else block
=> nil
[1] pry(main)> puts "parents process pid is #{Process.pid}"
parents process pid is 50844
=> nil
[2] pry(main)> if fork
[2] pry(main)*   puts "entered the if block from #{Process.pid}"
[2] pry(main)* else
[2] pry(main)*   puts "entered the else block from #{Process.pid}"
[2] pry(main)* end
entered the if block from 50844
entered the else block from 50892
=> nil