Skip to content

Instantly share code, notes, and snippets.

@therealadam
Created June 19, 2012 12:48
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 therealadam/2953970 to your computer and use it in GitHub Desktop.
Save therealadam/2953970 to your computer and use it in GitHub Desktop.
Baby's first concurrent program
# http://weblog.therealadam.com/2012/06/19/getting-started-with-ruby-concurrency-using-two-simple-classes/
require 'thread'
require 'timeout'
module Work
@queue = Queue.new
@n_threads = 2
@workers = []
@running = true
Job = Struct.new(:worker, :params)
module_function
def enqueue(worker, *params)
@queue << Job.new(worker, params)
end
def start
@workers = @n_threads.times.map { Thread.new { process_jobs } }
end
def process_jobs
while @running
job = nil
Timeout.timeout(1) do
job = @queue.pop
end
job.worker.new.call(*job.params)
end
end
def drain
loop do
break if @queue.empty?
sleep 1
end
end
def stop
@running = false
@workers.join
end
end
class EchoJob
def call(message)
puts message
end
end
Thread.abort_on_exception = true
10.times { |n| Work.enqueue(EchoJob, "I counted to #{n}") }
# Process jobs in another thread(s)
Work.start
# Block until all jobs are processed, then return
Work.drain
# Stop the workers
Work.stop
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment