Tom*_*art 5 ruby multithreading ruby-1.9
我有以下代码(来自Ruby教程):
require 'thread'
count1 = count2 = 0
difference = 0
counter = Thread.new do
loop do
count1 += 1
count2 += 1
end
end
spy = Thread.new do
loop do
difference += (count1 - count2).abs
end
end
sleep 1
puts "count1 : #{count1}"
puts "count2 : #{count2}"
puts "difference : #{difference}"
counter.join(2)
spy.join(2)
puts "count1 : #{count1}"
puts "count2 : #{count2}"
puts "difference : #{difference}"
Run Code Online (Sandbox Code Playgroud)
这是一个使用的例子Mutex.synchronize.在我的计算机上,结果与教程完全不同.打电话后join,计数有时相等:
count1 : 5321211
count2 : 6812638
difference : 0
count1 : 27307724
count2 : 27307724
difference : 0
Run Code Online (Sandbox Code Playgroud)
有时不是:
count1 : 4456390
count2 : 5981589
difference : 0
count1 : 25887977
count2 : 28204117
difference : 0
Run Code Online (Sandbox Code Playgroud)
我不明白,0即使计数显示的数字非常不同,差异仍然存在.
该add操作可能如下所示:
val = fetch_current(count1)
add 1 to val
store val back into count1
Run Code Online (Sandbox Code Playgroud)
和类似的东西count2.Ruby可以在线程之间切换执行,因此它可能无法完成对变量的写入,但是当CPU返回到线程时,它应该从它被中断的行继续,对吧?
并且仍然只有一个线程正在写入变量.如何在loop do块内部count2 += 1执行更多次?
执行
puts "count1 : #{count1}"
Run Code Online (Sandbox Code Playgroud)
需要一些时间(尽管可能很短)。它不是在实例中完成的。因此,连续两行并不神秘:
puts "count1 : #{count1}"
puts "count2 : #{count2}"
Run Code Online (Sandbox Code Playgroud)
显示不同的计数。简单地说,线程经历了一些循环周期并在执行counter第一个循环时增加了计数。puts
同样,当
difference += (count1 - count2).abs
Run Code Online (Sandbox Code Playgroud)
当被计算时,原则上计数可以在被引用count1之前被引用时递增count2。但在该时间跨度内并没有执行任何命令,我猜测其引用所花费的时间count1比线程经过另一次循环所花费的时间要短得多counter。请注意,前者完成的操作是后者完成的操作的适当子集。如果差异足够大,这意味着counter线程在方法的参数调用期间没有经历循环周期-,则count1和count2将显示为相同的值。
预测是,如果您在引用之后count1但在引用之前进行一些昂贵的计算count2,则会difference显示:
difference += (count1.tap{some_expensive_calculation} - count2).abs
# => larger `difference`
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1580 次 |
| 最近记录: |