Working with Unix Processes メモ

プロセスが持っているもの

ID

Process.pid

用途

  • シグナルを送る
  • ログファイル内でプロセスを識別

Process.ppid

ファイルディスクリプタ

passwd = File.open('/etc/passwd')
puts passwd.fileno

扱えるリソースの限度

Process.getrlimit(:NOFILE) # => [256, 9223372036854775807]
Process.setrlimit(:NOFILE, 10000)
ri Process.getrlimit

引数

ARGV[0]

環境

ENV["PATH"]

名前

$PROGRAM_NAME

終了コード

exit
exit 10
at_exit{puts "bye!"}
exit
abort        # 終了コード1
abort "hoge" # 標準エラーに表示される

プロセスができること

fork

puts "親プロセスID: #{Process.id}"
if fork
  puts "親プロセスID: #{Process.id}"
else
  puts "子プロセスID: #{Process.id}"
end
fork do
  # 子プロセス
end

wait

Process.wait  # => pid
Process.wait2 # => [pid, status]
child_pid = fork do
  # 子プロセス
  exit 10
end

pid, status = Process.waitpid2(child_pid)
puts status.exitstatus

親なしになる

fork do
  while true
    sleep 1
    puts "hello"
  end
end
abort "Bye!"

ゾンビになる

child_pid = fork do
  # 子プロセス
end

puts child_pid
sleep 20
ps -ho pid,state -p {プロセスID}
child_pid = fork do
  # 子プロセス
end

Process.detach(child_pid)
sleep 20

シグナルを受け取る

child_pid = fork do
  # 子プロセス
  sleep 3
end

trap(:CHLD) do
  puts "Hey!"
  exit
end

loop do
  sleep 1
end

他のプロセスと通信する

パイプ

r, w = IO.pipe
w.write("Hello")
w.close
puts r.read
r, w = IO.pipe
fork do
  r.close
  5.times do |i|
    sleep 1
    w.puts i
  end
end
w.close
while s = r.gets
  puts s
end

パイプは一方向

ソケット

require 'socket'
child_socket, parent_socket = Socket.pair(:UNIX, :DGRAM, 0)
fork do
  parent_socket.close

  5.times do |i|
    s = child_socket.recv(1000)
    puts s
    child_socket.send("CHILD: You said '#{s}'?", 0)
  end  
end
child_socket.close
5.times do |i|
  parent_socket.send("Hello #{i}!", 0)
end
5.times do
  puts parent_socket.recv(1000)
end

ソケットは双方向

デーモンになる

Process.daemon
10.times do |i|
  system "say #{10 - i}"
  sleep 1
end

Working With Unix Processes

Working With Unix Processes