ruby – 多线程循环

前端之家收集整理的这篇文章主要介绍了ruby – 多线程循环前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有以下代码( from a Ruby tutorial):
  1. require 'thread'
  2.  
  3. count1 = count2 = 0
  4. difference = 0
  5. counter = Thread.new do
  6. loop do
  7. count1 += 1
  8. count2 += 1
  9. end
  10. end
  11. spy = Thread.new do
  12. loop do
  13. difference += (count1 - count2).abs
  14. end
  15. end
  16. sleep 1
  17.  
  18. puts "count1 : #{count1}"
  19. puts "count2 : #{count2}"
  20. puts "difference : #{difference}"
  21. counter.join(2)
  22. spy.join(2)
  23. puts "count1 : #{count1}"
  24. puts "count2 : #{count2}"
  25. puts "difference : #{difference}"

这是使用Mutex.synchronize的一个例子.在我的计算机上,结果与教程完全不同.在调用join之后,计数有时相等:

  1. count1 : 5321211
  2. count2 : 6812638
  3. difference : 0
  4. count1 : 27307724
  5. count2 : 27307724
  6. difference : 0

有时不是:

  1. count1 : 4456390
  2. count2 : 5981589
  3. difference : 0
  4. count1 : 25887977
  5. count2 : 28204117
  6. difference : 0

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

添加操作可能如下所示:

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

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

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

解决方法

执行
  1. puts "count1 : #{count1}"

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

  1. puts "count1 : #{count1}"
  2. puts "count2 : #{count2}"

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

同样,何时

  1. difference += (count1 - count2).abs

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

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

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

猜你在找的Ruby相关文章