ruby - 多线程循环

标签 ruby multithreading ruby-1.9

我有以下代码 ( from a Ruby tutorial ):

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}"

这是一个使用Mutex.synchronize 的例子。在我的电脑上,结果与教程大不相同。调用 join 后,计数有时相等:

count1 :  5321211
count2 :  6812638
difference : 0
count1 :  27307724
count2 :  27307724
difference : 0

有时不是:

count1 :  4456390
count2 :  5981589
difference : 0
count1 :  25887977
count2 :  28204117
difference : 0

我不明白为什么差异仍然是 0,即使计数显示的数字非常不同。

add 操作可能如下所示:

val = fetch_current(count1)
add 1 to val
store val back into count1

count2 类似的东西。 Ruby 可以在线程之间切换执行,因此它可能不会完成对变量的写入,但是当 CPU 返回到线程时,它应该从被中断的行继续,对吗?

而且仍然只有一个线程正在写入变量。在 loop do block 内,count2 += 1 怎么可能被执行更多次?

最佳答案

执行

puts "count1 :  #{count1}"

需要一些时间(虽然可能很短)。它不是在一个实例中完成的。因此,连续两行并不神秘:

puts "count1 :  #{count1}"
puts "count2 :  #{count2}"

显示不同的计数。简单地说,counter 线程经过一些循环并在执行第一个 puts 时递增计数。

同样,当

difference += (count1 - count2).abs

被计算时,原则上计数可能会递增,而 count1count2 被引用之前被引用。但是在那个时间跨度内没有执行任何命令,我猜测它引用 count1 所花费的时间比 counter 线程所花费的时间要短得多通过另一个循环。请注意,在前者中完成的操作是在后者中完成的操作的适当子集。如果差异足够大,这意味着 counter 线程在 - 方法的参数调用期间没有经历循环周期,则 count1count2 将显示为相同的值。

一个预测是,如果你在引用 count1 之后但在引用 count2 之前进行一些昂贵的计算,那么 difference 将会出现:

difference += (count1.tap{some_expensive_calculation} - count2).abs
# => larger `difference`

关于ruby - 多线程循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13064113/

相关文章:

ruby - TCP 服务器错误 : Address already in use - bind(2)

mysql - 汇总 Ruby on Rails 中表中的条目数量

ruby - 从源代码安装 Ruby1.9 时找不到 OpenSSL header /库

Ruby 1.9.3 Dir.glob 奇怪的递归匹配行为

ruby - 如何设置变量除以四舍五入到小数点后 0 位?

ruby - 为什么 resque 使用子进程来处理队列中的每个作业?

android - 如何在 SurfaceView 中动态改变图像?

java - 为什么我的 java 长时间运行的线程(5k+ 线程)没有利用所有机器内核(12 核)?

java - 让java程序的一部分等待......而不是整个程序

ruby - 为什么在 Ruby 1.9 中两个具有相同字节和编码的字符串不相同?