2010-04-12 3 views
3

Je travaille sur des machines Linux partagées avec entre 4 et 24 cœurs. Pour tirer le meilleur parti d'eux, j'utilise le code suivant pour détecter le nombre de processeurs de mes scripts Ruby:Détecter le nombre de processeurs IDLE ruby ​​

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

(peut-être il y a un moyen pur-ruby de le faire?)

Mais parfois, un collègue utilise six ou huit des 24 cœurs. (comme vu par dessus). Comment puis-je obtenir une estimation du nombre de processeurs actuellement inutilisés que je peux utiliser sans que personne ne soit contrarié?

Merci!

+0

semble gentil avec moi. vous auriez besoin d'une extension c pour cela de toute façon. – mikezter

Répondre

3

Vous pouvez utiliser les données du système de fichiers /proc pour obtenir des informations d'affinité de processeur pour les processus en cours d'exécution. Ce qui suit devrait vous donner le nombre de processeurs actuellement utilisés (Note: Je n'ai pas une boîte Linux ou Ruby si ce code pratique est non testé, mais vous pouvez avoir l'idée):

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 

Edit: J'ai vérifié que le code ci-dessus fonctionne (j'utilisais Ruby 1.9)

+1

merci pour la réponse! Je l'ai modifié un peu pour tenir compte des fluctuations dans l'utilisation du processeur (voir ma réponse ci-dessous) –

+1

Étant donné la fréquence à laquelle les nouveaux processus démarrent/arrêtent/bloquent/dorment/réveillent/etc, l'exécution de ce script ne vous donnera pas beaucoup d'informations . Je recommande de l'exécuter plusieurs fois avec un délai intermédiaire et de faire la moyenne des résultats. Cela ne fait que suivre les processus en cours (supprimer l'instruction 'if' dans le premier bloc pour suivre * tous * les processus) et le lancement de Ruby peut être suffisant pour mettre en attente un processus en cours, donc je ne le ferais certainement pas. Je fais confiance à l'exactitude d'un seul passage. – bta

2

inspiré par la réponse de BTA, voici ce que je utilise:

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

Puisqu'il y a une prime sur cette question, vous devriez probablement ajouter ceci à votre question vers le haut au lieu de comme réponse. – bta

Questions connexes