おおいしつかさ


旅行とバイクとドライブと料理と宇宙が好き。
Ubie Discoveryのプログラマ。
Share:  このエントリーをはてなブックマークに追加

RubyのThreadとforkについて

 スレッドについてもうすこし調べてみました。

thread_list = Array.new  
2.times do |i|  
  thread_list << Thread.new(i) do |m|  
    1000000.times do |a|  
      if a % 200000 == 0  
        if m == 0  
          puts "one"  
        else  
          puts "   two"  
        end  
      end  
    end  
  end  
end  
thread_list.each {|t| t.join}  
 
1000000.times do |a|  
  if a % 200000 == 0  
    puts "      three"  
  end  
end  
 
puts "--end--"  

これの結果は

one  
   two  
one  
   two  
one  
   two  
one  
   two  
one  
   two  
      three  
      three  
      three  
      three  
      three  
--end--  

 joinで子スレッドが終了するのを待っていますね。これでは更新pingの速度も劇的に速くなるとはちょっと言いがたい。
ちなみにスレッド内の例外を処理したいときは、スレッド単位でrescueして安心してはいけなくて、なぜかといえばjoinで待っているスレッドでも例外が発生するからなのです。なので注意が必要です。

thread_list = Array.new  
begin  
2.times do |i|  
  thread_list << Thread.new(i) do |m|  
    1000000.times do |a|  
      if a % 200000 == 0  
        if m == 0  
          puts "one"  
        else  
          puts "   two"  
        end  
      end  
      raise "test e"  
    end  
  end  
end  
 
thread_list.each {|t| t.join}  
rescue  
  p $!  
end  
 
1000000.times do |a|  
  if a % 200000 == 0  
    puts "      three"  
  end  
end  
 
puts "--end--"  

結果は

one  
   two  
#<RuntimeError: test e>  
      three  
      three  
      three  
      three  
      three  
--end--  

こんな感じ。

 さらに子プロセスでやってみる。

fork do  
  2.times do |m|  
    1000000.times do |a|  
      if a % 200000 == 0  
        if m == 0  
          puts "one"  
        else  
          puts "   two"  
        end  
      end  
    end  
  end  
end  
 
1000000.times do |a|  
  if a % 200000 == 0  
    puts "      three"  
  end  
end  
 
puts "--end--"  

結果は

one  
      three  
      three  
      three  
      three  
      three  
--end--  
[tsukasa@] $ one                                                     [~/lesson]  
one  
one  
one  
   two  
   two  
   two  
   two  
   two  

 お、ぼくがやりたかった流れの処理になったようです。よかったよかった。というわけでkaeruspoonもfork doを使って子プロセスを作り、ブログ更新ping送信を発信するという処理にします。

 継続とかFiberとかもちょっと調べてみようかな(まだよくわかっていない)。