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