我有sinatra设置,听取github repo的提交。我当前设置的系统,监听帖子,然后将有效负载推送到有效负载阵列。然后我打电话给
@@payloads.each do .... whatever
如果有多个帖子来自github,即人们在@@payloads.each
运行时推送更多提交,会发生什么?如果有一个有效载荷,那么另一个有效载荷被驱动,payloads.each
呼叫圈是否又一次?或者是否进行了设置,以便在呼叫完成后.each
呼叫经过的有效负载数量一成不变?
答案 0 :(得分:1)
作为一个FYI,除非您同步访问,否则您可能会遇到读/写同一个数组的问题。看看Ruby的内置Queue类。它是Thread的一部分。
您可以拥有多个不会发生冲突的生产者/消费者。这是文档所说的内容:
此类提供了一种同步线程之间通信的方法。
示例:
require 'thread'
queue = Queue.new
producer = Thread.new do
5.times do |i|
sleep rand(i) # simulate expense
queue << i
puts "#{i} produced"
end
end
consumer = Thread.new do
5.times do |i|
value = queue.pop
sleep rand(i/2) # simulate expense
puts "consumed #{value}"
end
end
consumer.join
至于使用each
循环数组,我认为你应该使用语法:
loop do
break if @@payloads.empty?
end
each
意味着要迭代的有限元素集。描述说:
为self ....中的每个元素调用给定的块一次。
在其他语言中,您无法更改正在迭代的容器,因为元素的数量是在循环开始时设置的;尝试更改容器会引发错误。依靠each
允许你这样做可能会导致期望你会看到其他语言的行为;在我看来,你依赖于副作用或侧门,这不是一个好习惯。
loop
并不意味着因为它是一个简单的循环,你必须有条件地摆脱使用自己的逻辑。以下是loop
的示例:
loop do
print "Input: "
line = gets
break if !line or line =~ /^qQ/
# ...
end
没有假设元素的数量,它完全是开放式的。并且,它很容易爆发,因为Queue具有必要的empty?
方法。
这是我的0.02美元以及我是如何做到的。
查看页面右侧的“相关”主题以获得更多想法。
答案 1 :(得分:1)
只要@@payloads
是标准的ruby数组,推送的有效负载就应该包含在#each
次迭代中。
当一个线程迭代一个数组,另一个线程追加到同一个数组时,迭代线程将包含附加项。
Take a look at this gist有一个简单的程序来演示这种行为。一个线程迭代,而另一个线程添加到数组。由于ruby中线程调度的性质,每次结果可能都不同。