Created
June 19, 2012 12:48
-
-
Save therealadam/2953970 to your computer and use it in GitHub Desktop.
Baby's first concurrent program
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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