2022/06/11
Unix Processes
Our First Pipe
複数プロセス間でのやり取りにパイプを使用する。パイプはデータを単方向通信する。writerがwrite
した内容をreaderがread
できる。
irb(main):001:0> reader, writer = IO.pipe => [#<IO:fd 9>, #<IO:fd 10>] irb(main):002:0> writer.write("Into the pipe I go...") => 21 irb(main):003:0> writer.close => nil irb(main):004:0> puts reader.read Into the pipe I go... => nil
writeがclose
してからでないと,readerはread
できない。
Sharing Pipes
親と子プロセス間で,リソースは共有されるため,pipeも共有される。
irb(main):001:0> reader, writer = IO.pipe => [#<IO:fd 9>, #<IO:fd 10>] irb(main):002:1* fork do irb(main):003:1* reader.close irb(main):004:1* irb(main):005:2* 10.times do irb(main):006:2* writer.puts "Another one bites the dust" irb(main):007:1* end irb(main):008:0> end => 15983 irb(main):009:0> writer.close => nil irb(main):010:1* while message = reader.gets irb(main):011:1* $stdout.puts message irb(main):012:0> end Another one bites the dust Another one bites the dust Another one bites the dust Another one bites the dust Another one bites the dust Another one bites the dust Another one bites the dust Another one bites the dust Another one bites the dust Another one bites the dust
上記の例だと,親プロセスにwriterとreader,子プロセスにwriterとreaderがそれぞれ存在するため,不要な子プロセスのreader,親プロセスのwriterをclose
している。
Stream vs. Messages
Unix Socketsは同じ物理マシン上でやり取りできるソケットの一種。TCPソケットよりも高速。ソケットでは双方向通信が可能。
irb(main):001:0> require "socket" => true irb(main):002:0> child_socket, parent_socket = Socket.pair(:UNIX, :DGRAM, 0) => [#<Socket:fd 9>, #<Socket:fd 10>] irb(main):003:0> max_len = 1000 => 1000 irb(main):004:1* fork do irb(main):005:1* parent_socket.close irb(main):006:1* irb(main):007:2* 4.times do irb(main):008:2* instruction = child_socket.recv(max_len) irb(main):009:2* child_socket.send("#{instruction} accomplished!", 0) irb(main):010:1* end irb(main):011:0> end => 16197 irb(main):012:0> child_socket.close => nil irb(main):013:1* 2.times do irb(main):014:1* parent_socket.send("Heavy lifting", 0) irb(main):015:0> end => 2 irb(main):016:1* 2.times do irb(main):017:1* parent_socket.send("Feather lifting", 0) irb(main):018:0> end => 2 irb(main):019:1* 4.times do irb(main):020:1* $stdout.puts parent_socket.recv(max_len) irb(main):021:0> end Heavy lifting accomplished! Heavy lifting accomplished! Feather lifting accomplished! Feather lifting accomplished!
子プロセスが親プロセスから受信したメッセージに文字列を加えて,親プロセスに送信し,最後に親プロセスが受信したメッセージを出力している。
Daemon Processes
daemon processは,ターミナル上でユーザが支配できるというよりは,裏で動いているプロセス。代表的な例は,WebサーバーやDBサーバー。