Skip to content

Instantly share code, notes, and snippets.

@nanodeath
Created October 31, 2010 18:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nanodeath/656925 to your computer and use it in GitHub Desktop.
Save nanodeath/656925 to your computer and use it in GitHub Desktop.
require "thread"
require "monitor"
require "timeout"
class Worker < Thread
def initialize(joblist, mon, input_cv, output_cv)
@busy = false
@mon = mon
super do
while true
job = nil
mon.synchronize do
input_cv.wait_until { !joblist.empty? }
job = joblist.shift
@busy = true
end
expensive_computation
mon.synchronize do
@busy = false
output_cv.broadcast
end
end
end
end
def expensive_computation
# just an example
begin
Timeout::timeout(1) {
1.upto(2000000000) {}
}
rescue
end
end
def busy?
@mon.synchronize do
return @busy
end
end
end
mon = Object.new
mon.extend MonitorMixin
# signal to this cv when the joblist is added to
input_cv = mon.new_cond
# signal to this cv when a thread finishes
output_cv = mon.new_cond
joblist = (1..100).to_a
# Here we're adding some more data to the input queue
Thread.new do
5.times do |i|
mon.synchronize do
joblist << (i + 2) * 100
input_cv.signal
end
sleep 1
end
end
workers = []
100.times { workers << Worker.new(joblist, mon, input_cv, output_cv) }
mon.synchronize do
output_cv.wait_until { joblist.empty? && workers.find(&:busy?).nil? }
end
puts "joblist is empty (#{joblist.empty?}) and no busy workers found(#{workers.select(&:busy?).length == 0}): done!"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment