运行此
# in initialize
@queue = Queue.new
@threads = Array.new(NUM_THREADS) do
Thread.new do
until @queue.empty?
puts @queue.shift
end
end
end
# later in another method, calling
@threads.each { |t| puts t.alive? } # puts false
@queue.push('something else')
# new item is not processed by thread
如何保持Ruby线程处于活动状态,以便它可以继续接收队列中的内容?
答案 0 :(得分:0)
问题是在向队列添加任何内容之前初始化线程。线程在@queue.push
行运行之前开始并消亡。
如果要保持线程的活动,即使队列中没有任何内容,您也可以更改线程的逻辑,使其永远循环:
Thread.new do
loop do
if val = @queue.shift
puts val
end
end
end
你可以通过在线程循环中调用sleep
来减少CPU消耗,比如每次迭代睡眠时间为0.1秒,因此每秒最多可以处理10个项目。例如,在我的Ruby REPL中运行以下内容会将进程的CPU消耗从0%提高到25%(这是非常高的)
100.times { Thread.new { loop { } } }
但以下使用不到1%:
100.times { Thread.new { loop { sleep 0.1 } } }
除了在其中添加任意sleep
个数字之外,还有其他方法可以管理后台进程的CPU消耗:例如eventmachine,resque或sidekiq。
答案 1 :(得分:0)
您可能想使用Ruby核心库中的Queue。
方法pop
,deq
和shift
可用于从队列中检索数据。
根据文档,使用这些方法
如果队列为空,则调用线程被挂起,直到数据为空 推入队列。
使用Queue
,您的代码段看起来像这样
@queue = Queue.new
@threads = Array.new(NUM_THREADS) do
Thread.new do
while (item = @queue.shift)
puts item
end
end
end
# later in another method
@threads.each { |t| puts t.alive? } # true
@queue.push('something else') # is printed out
Queue#shift
保持线程等待,直到将某些内容推入队列为止。您仍然需要循环,以便在处理完该项目后,线程将保持活动,挂起状态,等待下一个项目。