2010-04-12 53 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