Anyway, for ReReplay I was initially using EventMachine, but I needed events to happen at very particular points in the future, and EventMachine’s granularity (which is at best 10ms) simply wasn’t good enough. Using threads I can have a granularity of under a millisecond. I was just sharing some commentary regarding what I learned while using monitors.
]]>So you still need two condition variables, even with only one monitor. The example is a bit more complicated now, and…I’m not sure exactly what the benefit of subclassing Thread is. But there you have it.
]]>I’m not sure I really like a solution that involves iterating over a list every time we want to see if we’re done — if you have a lot of worker threads (50? 100?) that’s a lot of unnecessary time spent inside the monitor (O(n) time on number of threads instead of O(1)).
Lastly, I disagree that adding new jobs during execution wouldn’t be easy — it would be as simple as adding the job to the queue and incrementing the results_unprocessed variable. (Not sure if the queue manipulation would need to be inside the q synchronize block, but whatever).
In any case, I’ll write up your idea and include it here, see if it makes more sense to me.
]]>The monitor construct is useful in a single case: when you want to make sure that at most one thread execute inside the monitor. Usually all threads wait for a condition before entering the monitor, does stuff, exits (or wait again), and signal.
To demonstrate it better, I think that you should have implemented the queue within the monitor as well because here you’re pop-ing with a synchronization construct, and monitoring the queue size in another one (without possibility to add new jobs in the queue easily).
I would have done everything with the monitor construct with:
- a Worker subclass of Thread with a busy? method
- a regular array joblist that you can test on empty?
Basically, you exit when joblist.empty? and not workers.find(&:busy?) which is easier to understand that test on a variable tracking the queue length.
]]>