2013-10-09 22 views
0

我試圖刮掉一些網站的信息,我從來沒有使用過線程。我撞壞了這份測試模仿我想要做的事:變量的範圍在線程

require 'thread' 
mutex = Mutex.new 
mut = Mutex.new 
hash = {} 
n = 0 
a = [] 
b = [] 
# x = 0 
10.times do |i| 
a << Thread.new(i) do |top_index| 
    mutex.synchronize do 
    hash[top_index] = [] 
    sleep 0.2 
    100.times do |sub_index| 
     b << Thread.new(top_index, sub_index, hash) do |t, s, my_hash| 
     mut.synchronize do 
      r = s 
      sleep 0.2 
      my_hash[t].push(s) 
     end 
     end 
    end 
    b.each {|y| y.join } 
    puts "sub: #{top_index} - #{hash[top_index].length}" 
    puts hash[top_index] 
    end 
end 
end 
a.each {|q| q.join } 
hash.each { |key, value| n += value.length } 
puts "Final Tally - #{n}" 

隨着sleep站在一段RESTClient實現get請求,並且數字代表我從刮下的訂購和push ING的一些信息現場。但是,在查看所有輸入的順序時,我注意到數組中的模式,所以我想知道在一個線程中分配r是否會影響其他線程中的值。但這沒有意義,因爲這會嚴重限制其對併發請求的有用性。另外,我想因爲一切都是併發的(或者表現爲併發),它應該在幾秒鐘內返回睡眠定時器,但實際上它需要很長時間。

我剛測試過它,實際上比沒有線程需要更長的時間嗎?

螺紋總時間:204.04028

向總:203.133638

所以,現在我很迷茫。

+0

線程,其整個操作被包裹在一個互斥? –

+0

這不好嗎?我沒有發現嵌套線程,但我也沒有看到有人說不這樣做。如果沒有它,它就無法工作。 – MCB

+0

也許你可以解釋「沒有它真的沒有工作」的意思。如果事實證明您確實需要同步部分工作,請隔離該部分並且只能同步儘可能少的代碼。 –

回答

1

我不知道你注意到了什麼「模式」但一般來說,您在示例中使用Thread初始值設定項的方式應該按照您的預期工作。

我剛剛測試過它,它實際上比沒有線程需要更長的時間?

這是因爲你正在同步字面上所有你正在做的工作與這些線程。所以沒有併發。因此,單線程解決方案勝過「多線程」解決方案是有道理的,因爲後者只是做與前者相同的所有工作(以相同的順序),並且產生線程的額外開銷(並使它們等待)。

您不需要同步這些操作。 Ruby解釋器有一個global interpreter lock,它可以防止開發人員在低級語言中遇到的大多數競爭條件。您想要使用Mutex的主要場景是,當可能發生某些事情時外部需要同步的紅寶石土地(例如,某些較低級別的系統操作)。

這裏是你的榜樣的精簡版(不同步)的作品就好了:

require 'thread' 

hash = {} 
outer_threads = [] 
inner_threads = [] 

10.times do |i| 
outer_threads << Thread.new(i) do |top_index| 
    hash[top_index] = [] 
    sleep 0.2 
    20.times do |sub_index| 
    inner_threads << Thread.new(top_index, sub_index, hash[top_index]) do |t, s, arr| 
     sleep 0.2 
     arr.push(s + 1) 
    end 
    end 
    inner_threads.each(&:join) 
end 
end 

outer_threads.each(&:join) 

# Verify that the hash is populated with arrays comprising the numbers 1 to 20, 
# as we would expect. 
hash.each do |key, value| 
    puts "#{key}: #{value.sort.join(', ')}" 
end