なるほどUNIXプロセス
第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プログラミングとはプログラミングの一般のスキル