2010-04-12 70 views
3

我在4至24个核心的共享Linux机器上工作。为了让他们尽其用,我用下面的代码来检测处理器的数量从我的Ruby脚本:检测IDLE处理器的数量ruby

return `cat /proc/cpuinfo | grep processor | wc -l`.to_i 

(也许有这样做的纯Ruby的方式?)

但有时一个同事正在使用24个内核中的6个或8个。 (如通过顶部看到的)。如何估算当前未使用的处理器数量,而不会让任何人感到不安?

谢谢!

+0

似乎对我很好。无论如何你都需要一个C扩展。 – mikezter 2010-04-14 12:35:03

回答

3

您可以使用/proc文件系统中的数据获取正在运行的进程的CPU关联信息。下面应该给你的CPU的数量目前正在使用(注:我没有一台Linux或Ruby盒旁边所以这段代码是未经测试,但你可以得到的想法):

def processors_in_use 
    procs=[] 
    Dir.glob("/proc/*/stat") {|filename| 
     next if File.directory?(filename) 
     this_proc=[] 
     File.open(filename) {|file| this_proc = file.gets.split.values_at(2,38)} 
     procs << this_proc[1].to_i if this_proc[0]=="R" 
    } 
    procs.uniq.length 
end 

def num_processors 
    IO.readlines("/proc/cpuinfo").delete_if{|x| x.index("processor")==nil}.length 
end 

def num_free_processors 
    num_processors - processors_in_use 
end 

def estimate_free_cpus(count, waittime) 
    results=[] 
    count.times { 
     results << num_free_processors 
     sleep(waittime) 
    } 
    sum=0 
    results.each {|x| sum += x} 
    (sum.to_f/results.length).round 
end 

编辑:我验证了上面的代码工作(我使用Ruby 1.9)

+1

感谢您的回复! 我修改了一下,以说明处理器使用的波动(请参阅下面的答案) – 2010-04-29 11:25:43

+1

考虑到新进程启动/停止/阻止/休眠/唤醒/等的频率,运行此脚本一次不会给您提供太多信息。我建议将它在几次之间运行一段时间,然后对结果进行平均。这只会跟踪当前正在运行的进程(删除第一个块中的if语句以跟踪所有进程),并且启动Ruby的行为足以导致正在运行的进程被暂停,所以我绝对不会这样做,不要相信单次运行的准确性。 – bta 2010-04-29 23:14:49

2

启发BTA的答复,这是我使用的是什么:

private 
def YWSystemTools.numberOfActiveProcessors # internal 
    processorForProcs = [] 
    processFiles  = Dir.glob("/proc/*/stat") 
    raise IOError, 'Cannot find /proc/*/stat files. Are you sure this is a linux machine?' if processFiles.empty? 

    processFiles.each do |filename| 
     next if File.directory?(filename) # because /proc/net/stat is a directory 
     next if !File.exists?(filename) # may have disappeared in the meantime 
     this_proc = [] 
     File.open(filename) { |file| this_proc = file.gets.split.values_at(2,38) } 
     processorForProcs << this_proc[1].to_i if this_proc[0]=="R" 
    end 
    processorsInUse = processorForProcs.uniq 
    return(processorsInUse.length) 
end 
public 

def YWSystemTools.numberOfAvailableProcessors 
    numberOfAttempts = 5 
    $log.info("Will determine number of available processors. Wait #{numberOfAttempts.to_s} seconds.") 
    #we estimate 5 times because of local fluctuations in procesor use. Keep minimum. 
    estimationsOfNumberOfActiveProcessors = [] 
    numberOfAttempts.times do 
     estimationsOfNumberOfActiveProcessors << YWSystemTools.numberOfActiveProcessors 
     sleep(1) 
    end 
    numberOfActiveProcessors = estimationsOfNumberOfActiveProcessors.min 
    numberOfTotalProcessors = number_of_processors() 

    raise IOError, '!! # active Processors > # processors' if numberOfActiveProcessors > numberOfTotalProcessors 

    numberOfAvailableProcessors = numberOfTotalProcessors - numberOfActiveProcessors 
    $log.info("#{numberOfAvailableProcessors} out of #{numberOfTotalProcessors} are available!")   
    return(numberOfAvailableProcessors) 
end 
+1

由于在这个问题上存在悬而未决的问题,因此您应该将此添加到您的问题顶部而不是作为答案。 – bta 2010-04-29 23:19:52