On 13.09.2008 22:59, David Masover wrote:
> 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?

The usual solution is that the queue will not "go out of scope" before 
the thread dies.  In a farmer worker scenario (or however you call it) 
the farmer distributes work and is also often responsible for collecting 
results.  If there is no work left he needs to notify workers of this 
fact so they can react appropriately (die).

If I implement such a scenario I define a terminator (you used nil for 
that) that is sent n times down the queue (n = # threads).  Then the 
main thread joins all threads and that way you can be sure that all work 
is done when main thread exits.

Kind regards

	robert