Hatena::Grouparaistudy

czk-htnの日記

2006-08-17

[]11. スレッドとプロセス (3)

11.4 複数プロセスの実行

  • Kernel.system
    • 与えられた外部コマンドをサブプロセスで実行する
    • 正常時にtrueを返す(失敗時はfalse)
    • 失敗時、子プロセスの終了コードは$?に格納
    • コマンドの出力は呼び出し元と同じ出力先
  • バッククォート
  • IO.popen
  • Kernel.fork
    • 親には子プロセスID、子にはnilが返される
  • Kernel.exec
    • 与えられた外部コマンドで現在のプロセスを置き換える(外部コマンド終了と同時にプロセス終了?)
    • 呼び出した側は非同期で後の処理を続行する
  • Kernel.trap
    • 子プロセスが終了した時のシグナルを受け取る
systemとバッククォートによる違い
puts "Kernel.system------------------------------"
puts system("ls *.rb")
puts "BackQuote------------------------------"
puts `ls *.rb`
% ruby sample04.rb
Kernel.system------------------------------
sample01.rb sample02.rb sample03.rb sample04.rb
true
BackQuote------------------------------
sample01.rb
sample02.rb
sample03.rb
sample04.rb
popenでフォークした自身とやり取りするサンプル
pipe = IO.popen("-","w+")
if pipe
  pipe.puts "Get a Job!"
  $stderr.puts "Child says '#{pipe.gets.chomp}'"
else
  $stderr.puts "Dad says '#{gets.chomp}'"
  puts "OK"
end
% ruby sample05.rb
Dad says 'Get a Job!'
Child says 'OK'
systemとexecの違い
system "echo *"
system "echo", "*"
exec "echo *"
exec "echo", "*"
% ruby sample06.rb
sample01.rb sample02.rb sample03.rb sample04.rb sample05.rb sample06.rb sample07.rb
*
sample01.rb sample02.rb sample03.rb sample04.rb sample05.rb sample06.rb sample07.rb
Kernel.forkのサンプル

だけど例題通りにいかない。なぜ??

puts "Parent pid #{$$}"
trap("CLD") {
  pid = Process.wait
  puts "Child pid #{pid}: terminated"
  exit
}
system("echo Child pid $$") if fork == nil
puts "Parent pid #{$$}: terminated"
% ruby sample07.rb
Parent pid 598
Child pid 600
Child pid 600: terminated
Child pid 599: terminated
IO.popenにブロックを関連づけ
IO.popen("echo *.rb") { |f| puts "Files #{f.gets}" }
% ruby sample08.rb
Files sample01.rb sample02.rb sample03.rb sample04.rb sample05.rb sample06.rb sample07.rb sample08.rb
Kernel.forkにブロックを関連づけ
puts "#{$0} #{$$}"
fork do
  puts "In child, pid #{$$}"
  exit 99
end
pid = Process.wait
puts "Child terminated, pid = #{pid}, exit code = #{$? >> 8}, orgcode=#{$?}"
printf("%b, %b\n", $? >> 8, $?)
% ruby sample09.rb
sample09.rb 604
In child, pid 605
Child terminated, pid = 605, exit code = 99, orgcode = 25344
1100011, 110001100000000

[] あとで解決する (子プロセス)

  • sample07が期待通りに動かない理由
    • 2つの子プロセスIDが返る理由
    • 最後の"Parent terminated"が表示されない理由

(2006.11.05 追記) id:czk-htn:20061106 いまだ未解決

トラックバック - http://araistudy.g.hatena.ne.jp/czk-htn/20060817