lib/picky/cores.rb in picky-3.1.8 vs lib/picky/cores.rb in picky-3.1.9
- old
+ new
@@ -4,19 +4,21 @@
# Handles processing over multiple cores.
#
class Cores # :nodoc:all
- # Pass it an ary or generator.
+ # Pass it an ary.
#
- # generator = (1..10).each
- # forked generator, :max => 5 do |element|
+ # ary = (1..10).to_a
+ # forked ary, :max => 5 do |element|
#
# end
#
# Options include:
# * max: Maximum # of processors to use. Default is all it can get.
+ # * amount: An exactly defined amount of processors to use.
+ # * randomly: Whether to use random order or not.
#
def self.forked elements, options = {}, &block
return if elements.empty?
raise "Block argument needed when running Cores.forked" unless block_given?
@@ -27,42 +29,60 @@
elements = elements.dup
elements = elements.sort_by { rand } if options[:randomly]
# Get the maximum number of processors.
#
- max = max_processors options
- processing = 0
+ max = max_processors options
- loop do
- while processing < max
- # Get the next element
- #
- element = elements.shift
- break unless element
- processing += 1
+ # Decide whether to use forking.
+ #
+ if fork?(max)
+ processing = 0
- # Fork and yield.
+ loop do
+ while processing < max
+ # Get the next element
+ #
+ element = elements.shift
+ break unless element
+ processing += 1
+
+ # Fork and yield.
+ #
+ Process.fork do
+ sleep 0.05*processing
+ block.call element
+ end
+ end
+
+ # Block and wait for any child to finish.
#
- Process.fork do
- sleep 0.05*processing
- block.call element
+ begin
+ Process.wait 0
+ rescue Errno::ECHILD => e
+ break
+ ensure
+ processing -= 1
end
end
-
- # Block and wait for any child to finish.
- #
- begin
- Process.wait 0
- rescue Errno::ECHILD => e
- break
- ensure
- processing -= 1
- end
+ else
+ elements.each &block
end
end
+ # Do not fork if there is just one processor,
+ # or as in Windows, if there isn't the
+ # possibility of forking.
+ #
+ def self.fork? max_processors
+ max_processors > 1 && Process.respond_to?(:fork)
+ end
+
# Return the number of maximum usable processors.
+ #
+ # Options
+ # max: The maximum amount of cores used.
#
def self.max_processors options = {}
options[:amount] || [number_of_cores, (options[:max] || Infinity)].min
end
\ No newline at end of file