加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby – 多线程循环

发布时间:2020-12-16 20:57:14 所属栏目:百科 来源:网络整理
导读:我有以下代码( from a Ruby tutorial): require 'thread'count1 = count2 = 0difference = 0counter = Thread.new do loop do count1 += 1 count2 += 1 endendspy = Thread.new do loop do difference += (count1 - count2).abs endendsleep 1puts "count1
我有以下代码( 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`

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读