enq (enqueue) method or its synonym push.
deq (dequeue) method as needed.
(The pop and shift methods are synonyms for deq.)
deq
method blocks if the queue is
empty and waits until the producer thread adds a value to the queue.
map with
a concurrent inject.
Ejemplo de uso:
if $0 == __FILE__
a = if ARGV.empty?
[-2,-1,0,1,2]
else
ARGV.map &:to_f
end
mapper = lambda {|x| x*x } # Compute squares
injector = lambda {|total,x| total+x } # Compute sum
result = a.conject(0, mapper, injector) # => 10
puts result
end
Código:
[~/ruby/threads(master)]$ cat conject.rb
require 'thread'
module Enumerable
# Concurrent inject: expects an initial value and two Procs
def conject(initial, mapper, injector)
# Use a Queue to pass values from mapping threads to injector thread
q = Queue.new
count = 0 # How many items?
each do |item| # For each item
Thread.new do # Create a new thread
q.enq(mapper[item]) # Map and enqueue mapped value
end
count += 1 # Count items
end
t = Thread.new do # Create injector thread
x = initial # Start with specified initial value
while(count > 0) # Loop once for each item
x = injector[x,q.deq] # Dequeue value and inject
count -= 1 # Count down
end
x # Thread value is injected value
end
t.value # Wait for injector thread and return its value
end
end