> I'd like to detect "no work left" as a case of the "farmer" going out of
> scope, if possible.

In principle, if the Farmer is an object, then it can have a finalizer 
which sends the terminate message to all the workers. The finalizer 
won't be called immediately when the Farmer goes out of scope, but at 
some time later.

In practice, it isn't easy to do. The finalizer is only called *after* 
the farmer has been destroyed, so you can't use any methods or instance 
variables on it. And I find it very hard to demonstrate in practice. The 
following attempt is broken and I can't see what's wrong:

  #---- 8< --------------
  require 'thread'

  class Farmer
    attr_reader :queue, :workers

    def self.cleanup(workers)
      lambda { |id|
        workers.each { |t| p t; Thread.kill(t) }
      }
    end

    def self.create
      farmer = new
      workers = farmer.workers
      ObjectSpace.define_finalizer(farmer, cleanup(workers))
      farmer
    end

    def self.make_worker(queue)
      Thread.new do
        loop do
          puts queue.pop
        end
      end
    end

    def initialize
      @workers = []
      @queue = Queue.new
    end

    def add_worker
      @workers << self.class.make_worker(queue)
    end

    def push(x)
      @queue.push(x)
    end
  end

  def testit
    f = Farmer.create
    3.times { f.add_worker }
    f.push("hello")
    f.push("world")
  end

  10.times { testit }
  GC.start
  # For some reason the farmers still exist
  ObjectSpace.each_object(Farmer) { |f| p f }
  puts "End of the world"

  sleep 1
  #---- 8< --------------

When I run this, I see that the finalizers are indeed called when ruby 
terminates - but not when garbage-collection is requested. Indeed, the 
Farmers remain in ObjectSpace even after garbage collection. I can't see 
why that should be.

I've tried to ensure that neither the finalizer lambda nor the worker 
threads have the farmer bound to their environment, and I can't see what 
else is holding a reference. This is with ruby 1.8.6 (2008-03-03 
patchlevel 114) [i686-linux]

Regards,

Brian.
-- 
Posted via http://www.ruby-forum.com/.