multithreading - ruby: waiting for a thread to release a resource -
i'm using ruby 1.9.3. have long-lived thread picks jobs queue. thread uses mutex protect critical section thread processing job. let's job data contains field item_id.
the main thread receives job details external source, including item_id, , enqueues jobs onto queue. it's possible main thread receive same item_id multiple times in different jobs.
the main thread has access thread's mutex , current job's item_id.
my goal prevent main thread enqueuing job item_id on queue, or being processed thread. if situation happens, main thread should block until item_id processed. main thread should block in situation, or when waiting external jobs. want avoid busy-waiting.
i tried using conditionvariable, doesn't work because main thread may call wait after worker calls signal upon concluding processing. causes deadlock because signal never called on conditionvariable again.
edit: i'm going simplify problem. care if incoming item_id being handled thread. if it's in queue hasn't been dequeued yet, won't care duplicate.
here's minimal sample:
require 'thread' class workerthread < thread attr_reader :item_id def initialize(queue) @queue = queue @item_id = nil super(&method(:main)) end private def main loop begin @item_id = @queue.deq print "[t] working on #{item_id}\n" sleep 1 print "[t] done #{item_id}\n" ensure @item_id = nil end end end end queue = sizedqueue.new(1) thread = workerthread.new(queue) produced_ids = (1..10).map{ rand(1..3) } # simulate item_ids external source. in reality, we'd continue receiving these indefinitely. print "[main] item_ids: #{produced_ids.inspect}\n" produced_ids.each |item_id| # yes, know race cond # i'm interested in how avoid busy-wait. while thread.item_id == item_id print "[main] waiting id #{item_id} finish\n" sleep 0.5 end queue.enq(item_id) print "[main] enqueued #{item_id} ---\n" end # possible race cond - testing anyway until queue.empty? , thread.item_id == nil sleep 0.5 end please not tell me have race condition if i've added comment in code.
Comments
Post a Comment