2012年10月25日木曜日

rubyのthread


Queue をpopするとき、空だと、Threadは、sleep(stop)するらしい。join中に、すべてのThreadが、sleep(stop)だと、dead lockとなるらしい。

indou@MacBook:work:$ cat ts2.rb
require 'thread'

array_size = ARGV[0].to_i

q = Queue.new
10.times {|i| q.push "no:#{i}"}
q.push nil

arrays = Array.new(array_size) do |i|
  Thread.new do
    while cnt = q.pop
      puts "Thread #{i}: no:#{cnt}"
    end
  end
end
arrays.each do |t|
  t.join
end

puts "finish!!"
indou@MacBook:work:$ ruby ts2.rb 1
Thread 0: job0
Thread 0: job1
Thread 0: job2
Thread 0: job3
Thread 0: job4
Thread 0: job5
Thread 0: job6
Thread 0: job7
Thread 0: job8
Thread 0: job9
finish!!
indou@MacBook:work:$ ruby ts2.rb 2
Thread 0: job0
Thread 0: job2
Thread 0: job3
Thread 0: job4
Thread 0: job5
Thread 0: job6
Thread 0: job7
Thread 0: job8
Thread 0: job9
Thread 1: job1
ts2.rb:17:in `join': deadlock detected (fatal)
     from ts2.rb:17:in `block in
'
     from ts2.rb:16:in `each'
     from ts2.rb:16:in `
'
indou@MacBook:work:$ diff ts2.rb ts2.2.rb
7c7,10
< q.push nil
---
> array_size.times do
>   puts "."
>   q.push nil
> end
indou@MacBook:work:$ ruby ts2.2.rb 1
.
Thread 0: job0
Thread 0: job1
Thread 0: job2
Thread 0: job3
Thread 0: job4
Thread 0: job5
Thread 0: job6
Thread 0: job7
Thread 0: job8
Thread 0: job9
finish!!
indou@MacBook:work:$ ruby ts2.2.rb 2
.
.
Thread 0: job0
Thread 0: job1
Thread 0: job2
Thread 0: job3
Thread 0: job4
Thread 0: job5
Thread 0: job6
Thread 0: job8
Thread 0: job9
Thread 1: job7
finish!!
indou@MacBook:work:$ 

Apple IDの情報が書き換えられていた。

今日、こんなメールが来た。

Apple ID名:************のアカウント情報が08/22/2012に変更されました。
指名
配送または請求先住所





Apple ID名: ***************  のアカウント情報が 08/22/2012 に変更されました。

氏名
配送または請求先住所
クレジットカード
このメールに心当たりがない場合、または第三者による不正アクセスが疑われる場合、今すぐiforgot.apple.comへアクセスしてパスワードの再設定を行ってください。

セキュリティ設定の確認と変更は、appleid.apple.comにサインインして行ってください。

このメールは自動返信メールです。誠に勝手ながらこのメールへの返信によるお問い合わせは承っておりません。ご質問がある場合はAppleサポートへアクセスしてください。

ご利用ありがとうございました。
Appleカスタマーサポー
アカウント情報を書き換えた覚えはないので、すぐパスワードを変更。

rubyのthreadでエラーが出ない。



このロジック。
ruby 1.8.7だと、正常に動作。

indou@MacBook:work:$ rvm use 1.8.7
Using /Users/indou/.rvm/gems/ruby-1.8.7-p370
indou@MacBook:work:$ ruby thread0.rb
500
Square(500) = 22.3606797749979
300
Square(300) = 17.3205080756888
.
indou@MacBook:work:$ 

ruby 1.9.3だと、正常に動作しない。

indou@MacBook:work:$ rvm use 1.9.3
Using /Users/indou/.rvm/gems/ruby-1.9.3-p194
indou@MacBook:work:$ ruby thread0.rb
500
300
.
indou@MacBook:work:$ 

indou@MacBook:work:$ sdiff thread0.rb.bk20121025 thread0.rb
require "thread"                              require "thread"

q = Queue.new                                   q = Queue.new

t = Thread.new do                              t = Thread.new do
  loop do                                     loop do
    n = q.pop                                       n = q.pop
    if n.to_i >= 0                                  if n.to_i >= 0
      val = Math::sqrt(n)                          |           begin
      puts "Square(#{n}) = #{val}"                     |             val = Math::sqrt(n)
                                         >             puts "Square(#{n}) = #{val}"
                                         >           rescue Exception => e
                                         >             p e
                                         >           end
    else                                       else
      puts "?"                                         puts "?"
    end                                            end
  end                                          end
end                                        end

while line = gets                              while line = gets
  if line.chop! == "."                                if line.chop! == "."
    break                                       break
  else                                          else
    q.push(line)                                  q.push(line)
  end                                          end
end                                        end
indou@MacBook:work:$ 

indou@MacBook:work:$ ruby  thread0.rb
500
#
.
indou@MacBook:work:$ 

なんだ。Math::sqrt(n)でエラーになってる。なんで、エラー表示されないんだろう。
indou@MacBook:work:$ cat ts.rb

n = gets
p Math::sqrt(n)
indou@MacBook:work:$ ruby ts.rb
500
ts.rb:3:in `sqrt': can't convert String into Float (TypeError)
     from ts.rb:3:in `
'
indou@MacBook:work:$

スレッドがなければエラー表示される。 

indou@MacBook:work:$ sdiff thread0.rb.bk20121025.1 thread0.rb
require "thread"                              require "thread"

q = Queue.new                                   q = Queue.new

t = Thread.new do                              t = Thread.new do
  loop do                                     loop do
    n = q.pop                                       n = q.pop
    if n.to_i >= 0                                  if n.to_i >= 0
      begin                                    |           val = Math::sqrt(n.to_i)
        val = Math::sqrt(n)                          |           puts "Square(#{n}) = #{val}"
        puts "Square(#{n}) = #{val}"                     <
      rescue Exception => e                          <
        p e                                    <
      end                                    <
    else                                       else
      puts "?"                                         puts "?"
    end                                            end
  end                                          end
end                                        end

while line = gets                              while line = gets
  if line.chop! == "."                                if line.chop! == "."
    break                                       break
  else                                          else
    q.push(line)                                  q.push(line)
  end                                          end
end                                        end
indou@MacBook:work:$ 

indou@MacBook:work:$ ruby  thread0.rb
500
Square(500) = 22.360679774997898
300
Square(300) = 17.320508075688775
.
indou@MacBook:work:$