Suppose I start a worker thread, like so:
require 'thread'
queue = Queue.new
Thread.new do
loop do
# Suppose this does something useful...
puts queue.pop
end
end
And I start sending things to that queue:
queue.push 'Hello, world!'
queue.push '(from inside the thread)'
...and so on.
Now, at some point, the queue will fall out of scope -- at which point, I'm
obviously not going to push anything onto it. It's also the only way to talk
to the thread, so the thread isn't going to be doing anything useful at this
point.
I'd like to collect that thread, but, of course, that's really impossible.
After all, the loop will never end, so the thread will never exit normally.
Without solving the Halting Problem, Ruby can't know that the thread won't do
anything useful, even if nothing else refers to it -- maybe it will push
something onto that queue, after all.
Now, I know the logical solution to this particular problem:
Thread.new do
until (item = queue.pop).nil?
puts item
end
end
But then, I have to remember to send that message just before the queue goes
out of scope:
queue.push nil
Is there any way to handle this gracefully? For example: Any way to tell that
the queue has gone out of scope, there? Or any way to fire any code right
before an object is collected?
Or do I always have to remember to kill that thread explicitly, somehow -- by
sending that nil, for example?