読者です 読者をやめる 読者になる 読者になる

なるほどUNIXプロセス

tatsu-zine.com

第20章まで。残りは付録。

第16章 プロセスはシグナルを受信できる

child_processes = 3
dead_processes = 0

child_processes.times do
  fork do
    sleep 3
  end
end

trap(:CHLD) do
  puts Process.wait
  dead_processes += 1
  exit if dead_processes == child_processes
end

loop do
  (Math.sqrt(rand(44)) ** 8).floor
  sleep 1
end
  • システムのデフォルトの振る舞いは保存できない
  • プロセスが終了する前にリソースを開放する、といった処理をさせたいだけなら at_exit フックを使えばよい

第17章 プロセスは通信できる

  • プロセス間通信(IPC: Inter Process Communication)
reader, writer = IO.pipe
writer.write "Into the pipe I go..."
writer.close
puts reader.read
reader.close
reader, writer = IO.pipe
reader.write "Trying to get the reader to write something"
# =>./sample_17_2.rb:2:in `write': not opened for writing (IOError)
#        from ./sample_17_2.rb:2:in `<main>'
reader, writer = IO.pipe

fork do
  reader.close

  10.times do
    writer.puts "Another one bites the dust"
  end

  writer.close
end

writer.close

while message = reader.gets
  $stdout.puts message
end

reader.close
require 'socket'

child_socket, parent_socket = Socket.pair(:UNIX, :DGRAM, 0)
maxlen = 1000

fork do
  parent_socket.close

  4.times do
    instruction = child_socket.recv(maxlen)
    child_socket.send("#{instruction} accompished!", 0)
  end
end

child_socket.close

2.times do
  parent_socket.send("Heavy lifting", 0)
end

2.times do
  parent_socket.send("Feather lifting", 0)
end

4.times do
  $stdout.puts parent_socket.recv(maxlen)
end
  • パイプは単方向、ソケットは双方向

第18章 デーモンプロセス

puts Process.pid
puts Process.getpgrp

fork {
  puts Process.pid
  puts Process.getpgrp
}

第19章 端末プロセスを作る

hosts = File.open("/etc/hosts")
python_code = %Q[import os; print os.fdopen(#{hosts.fileno}).read()]
exec 'python', '-c', python_code, { hosts.fileno => hosts }
puts "step 1"
system 'sleep 5'
puts "step 2"
Process.spawn 'sleep 5'
puts "step 3"

pid = Process.spawn 'sleep 5'
puts "step 4"
Process.waitpid(pid)
puts "step 5"
require 'open3'

Open3.popen3('grep', 'data') do |stdin, stdout, stderr|
  stdin.puts "some\ndata"
  stdin.close
  puts stdout.read
end

Open3.popen3('ls', '-uhh', err: :out) do |stdin, stdout, stderr|
  puts stdout.read
end

第20章 おわりに

  • Unixプログラミングとはプログラミングの一般のスキル