Skip to content

Instantly share code, notes, and snippets.

@mdunsmuir
Created February 26, 2014 01:59
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 mdunsmuir/9221944 to your computer and use it in GitHub Desktop.
Save mdunsmuir/9221944 to your computer and use it in GitHub Desktop.
require 'thread'
module KnifeDrawer
DEFAULT_NUM_FORKS = 4
def self.do_with_forks(tasks_hash, num_forks = DEFAULT_NUM_FORKS)
input_queue = Queue.new
output_queue = Queue.new
tasks_hash.each do |key, block|
input_queue.push([key, block])
end
num_forks.times.inject(Array.new) { |threads|
threads << Thread.new(input_queue) { |queue|
while task = input_queue.pop(true) rescue nil
key, block = *task
rd,wr = IO.pipe
if pid = fork
wr.close
payload = rd.read
rd.close
Process.wait(pid)
output_queue.push([key, Marshal.load(payload)])
else # in the fork
rd.close
wr.write Marshal.dump(block.call)
wr.close
exit
end
end # end while
} # end thread block
}.each { |thread| thread.join }
# make output queue into a hash
output = Hash.new
while key_value = output_queue.pop(true) rescue nil
key, value = *key_value
output[key] = value
end
output
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment