例えば、Twitterから同時にデータを取得するような例とかを考える。自分で結構考えてみたけど、処理が同時には走らない。どの辺がおかしいのかよくわからん。。。
#!/usr/bin/ruby -Ke require 'rubygems' require 'thread' require 'enumerator' require 'pp' require 'hpricot' require 'mechanize' require 'kconv' require 'yaml' gem 'twitter4r', '>=0.3.0' require 'twitter' $KCODE='e' class Friend attr_accessor :name attr_accessor :source attr_accessor :agent attr_accessor :following attr_accessor :followers attr_accessor :favorites attr_accessor :update def initialize(twitter) @name = twitter[:name] @agent = twitter[:agent] @url = "http://twitter.com/"+@name begin @source = Hpricot(agent.get_file(@url)) rescue Timeout::Error puts "caught Timeout::Error!" retry rescue WWW::Mechanize::ResponseCodeError => e case e.response_code when "404" raise "Net::HTTPNotFound!" when "502" puts "Net::HTTPBadGateway!" retry else raise "caught Excepcion!" + e.response_code end rescue => ex raise ex.message end self.set_count @source = "" rescue => ex raise ex.message end def set_count counter = 0 (@source/"span.stats_count").each{ |item| item = item.inner_text.gsub(/,/,"") #1.000みたいなのの処理 case counter when 0 @following = item when 1 @followers = item when 2 @favorites = item when 3 @update = item else end counter = counter+1 } end end friends = ["hayamiz","suztomo"].map{|name| puts Friend.new({ :name =>name, :agent => WWW::Mechanize.new }).name sleep 10 } t = Thread.start { friends = ["syou6162","y_benjo"].map{|name| puts Friend.new({ :name =>name, :agent => WWW::Mechanize.new }).name } } t.join
追記
これだとうまく行った。t1 = Thread.start { friends = ["syou6162","y_benjo","anemo","hirose30"].map{|name| puts Friend.new({ :name =>name, :agent => WWW::Mechanize.new }).name } } t2 = Thread.start { friends = ["hayamiz","suztomo","kis","hirose31"].map{|name| puts Friend.new({ :name =>name, :agent => WWW::Mechanize.new }).name } } t1.join t2.join
だけど、これだとうまく行かない。この差違がよく理解できない。
Thread.start { friends = ["syou6162","y_benjo","anemo","hirose30"].map{|name| puts Friend.new({ :name =>name, :agent => WWW::Mechanize.new }).name } }.join Thread.start { friends = ["hayamiz","suztomo","kis","hirose31"].map{|name| puts Friend.new({ :name =>name, :agent => WWW::Mechanize.new }).name } }.join
追追記
joinするとスレッドが終了するまでブロックされるらしい。ということでこんな感じにしたらうまくいった。t = [] t << Thread.start { friends = ["syou6162","y_benjo","anemo","hirose30"].map{|name| puts Friend.new({ :name =>name, :agent => WWW::Mechanize.new }).name } } t << Thread.start { friends = ["hayamiz","suztomo","kis","hirose31"].map{|name| puts Friend.new({ :name =>name, :agent => WWW::Mechanize.new }).name } } t.map{|t|t.join}
追追追記
だいぶ思ってた感じのコードになった。friends_tmp = ["syou6162","y_benjo","anemo","hirose30","hayamiz","suztomo","kis","hirose31"] friends = [] friends_tmp.each_slice(3){|item| friends.push item} pp friends t = [] friends.length.times{|i| t << Thread.start { friends[i].map{|name| friend = Friend.new({ :name =>name, :agent => WWW::Mechanize.new }) puts "#{friend.name} was created by thread number #{i}." } } } t.map{|t|t.join}
実行すると並列で3本のスレッドが走っていることが確認できる。走るからと言って大量に動かすのはやめましょう。。。
localhost% ruby easy_friend.rb [["syou6162", "y_benjo", "anemo"], ["hirose30", "hayamiz", "suztomo"], ["kis", "hirose31"]] hirose30 was created by thread number 1. kis was created by thread number 2. syou6162 was created by thread number 0. hirose31 was created by thread number 2. hayamiz was created by thread number 1. y_benjo was created by thread number 0. suztomo was created by thread number 1. anemo was created by thread number 0.
- 作者: Rubyサポーターズ,すがわらまさのり,寺田玄太郎,三村益隆,近藤宇智朗,橋立友宏,関口亮一
- 出版社/メーカー: 技術評論社
- 発売日: 2013/08/10
- メディア: 大型本
- この商品を含むブログ (22件) を見る