我正在阅读post的关于红宝石穿线的信息。有一个摘要:
q = Queue.new
producer = Thread.new {
c = 0
while true do
q << c
c += 1
puts "#{q.size} in stock"
end
}
consumer1 = Thread.new {
while true
val = q.shift
puts "Consumer - 1: #{val}"
end
}
consumer2 = Thread.new {
while true
val = q.shift
puts "Consumer - 2: #{val}"
end
}
[producer, consumer1, consumer2].each(&:join)
帖子说输出将为:
Thread 2: 25
Thread 1: 22
Thread 2: 26Thread 1: 27
Thread 2: 29
Thread 1: 28
原因是:
...一种非常常见的种族条件 ...
但是我无法复制该输出。作为Java程序员,我认为此处的输出与比赛条件无关。我相信这与puts
有关,但我对此一无所知。
这是怎么回事?
更新
感谢@Damien MATHIEU的帮助,这对红宝石新手有很多帮助。我发现了另一个answer in OS for STDOUT.sync = true
,很好地解释了我们为什么需要它以及它可能引起什么问题。
目的:
之所以这样做,是因为IO操作速度很慢,通常避免直接将每个字符写入控制台更有意义。
可能出现的问题(以及我的问题发生了什么):
在某些情况下,此行为会导致问题。假设您要构建一个进度条(运行一个循环,在大量计算之间输出单个点)。使用缓冲后,结果可能是一段时间没有任何输出,然后突然一次打印出多个点。
答案 0 :(得分:5)
这是因为puts
不会立即写入STDOUT
,而是会缓冲字符串并以更大的块写入。
您可以使用以下命令立即获得ruby的书写:
STDOUT.sync = true
这应该可以解决您的订购问题。