ruby – 多线程循环

前端之家收集整理的这篇文章主要介绍了ruby – 多线程循环前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有以下代码( 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.

添加操作可能如下所示:

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

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

并且仍然只有一个线程正在写入变量.怎么可能在循环内部阻塞,count2 = 1执行的次数多么多?

解决方法

执行
puts "count1 :  #{count1}"

需要一些时间(尽管可能很短).它不是在一个实例中完成的.因此,连续两条线并不神秘:

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

正在显示不同的数量.简单地说,计数器线程经历了一些循环周期并在执行第一次执行时递增计数.

同样,何时

difference += (count1 - count2).abs

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

预测将是,如果您在引用count1之后但在引用count2之前进行了一些昂贵的计算,那么差异将显示

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

猜你在找的Ruby相关文章