web-dev-qa-db-fra.com

Top et ps ne montrant pas le même résultat cpu

Ceci est lié à la question this .

Lorsque j'exécute top j'obtiens le résultat suivant:

enter image description here

pid 3038 utilise 18% de CPU, cependant lors de l'exécution

enter image description here

le résultat est de 5,5%. Et ce nombre ne semble pas changer avec le temps (c'est-à-dire lorsque vous exécutez la même commande un peu plus tard) ...

La commande ps fait-elle la moyenne de l'utilisation du processeur?

54
Theodor

man ps Dans la section NOTES.

   CPU usage is currently expressed as the percentage of time spent running
   during the entire lifetime of a process.  This is not ideal, and it does not
   conform to the standards that ps otherwise conforms to.  CPU usage is
   unlikely to add up to exactly 100%.

Et, je suppose que vous savez, mais vous pouvez également faire:

top -p <PID>

Edit : quant à votre commentaire sur une autre réponse;

" Hmm ouais je me demande comment obtenir ça (le pourcentage CPU instantané) de ps"

Réponse courte: vous ne pouvez pas.

Pourquoi en est-il ainsi?

C'est comme demander à quelqu'un de calculer la vitesse d'une voiture à partir d'une image.

Alors que top est un outil de surveillance, ps est un outil d'instantané. Considérez-le comme ceci: À un moment donné, un processus utilise le CPU ou non. Vous avez donc une charge de 0% ou 100% à ce moment précis.

Donner: si ps doit donner utilisation instantanée du CPU ce serait soit 0% soit 100%.

top d'autre part, conservez les nombres d'interrogation et calculez la charge au fil du temps.

ps aurait pu donner l'utilisation actuelle - mais cela nécessiterait de lire les données plusieurs fois et de dormir entre chaque lecture. Ce n'est pas le cas.

Calcul pour ps% cpu

ps calcule l'utilisation du processeur de la manière suivante:

 uptime = temps total de fonctionnement du système. 
 ps_time = temps de démarrage du processus mesuré en secondes à partir du démarrage. 
 pu_time = temps total pendant lequel le processus a utilisé le CPU. 
 
 ;; Le processus de secondes est en cours d'exécution: 
 Secondes = uptime - ps_time 
 ;; Utilisation: 
 Cpu_usage = pu_time * 1000/secondes 
 
 Print: cpu_usage/10 "." cpu_usage% 10 
 

Exemple: 
 
 Disponibilité = 344 545 
 Ps_time = 322 462 
 Pu_time = 3 383 
 
 Secondes = 344 545 - 322 462 = 22 083 
 cpu_usage = 3 383 * 1 000/22 083 = 153 
 
 impression: 153/10 "." 153% 10 => 15,3 
 

Le nombre imprimé est donc: la durée pendant laquelle le processus a utilisé le CPU pendant sa durée de vie. Comme dans l'exemple ci-dessus. Il l'a fait dans 15,3% de sa durée de vie. Dans 84,7% du temps, il n'y a pas eu de bug sur le CPU.

Récupération de données

ps, ainsi que top, utilise les données des fichiers stockés sous /proc/ - ou le système de pseudo-fichiers d'informations sur le processus .

Vous avez des fichiers à la racine de /proc/ Qui contiennent diverses informations sur l'état général du système. De plus, chaque processus a son propre sous-dossier /proc/<PID>/ Où les données spécifiques au processus sont stockées. Ainsi, par exemple, le processus de votre question avait un dossier à /proc/3038/.

Lorsque ps calcule l'utilisation du processeur, il utilise deux fichiers:

/ proc/uptime Temps de disponibilité du système (secondes) et temps passé en processus inactif (secondes). 
/proc/[PID]/stat Informations sur l'état du processus. 
  • De uptime, il utilise la première valeur ( uptime).
  • À partir de [PID]/stat, Il utilise les éléments suivants:
 # Nom Description 
 Temps CPU 14 heures passé en code utilisateur, mesuré en jiffies 
 Temps CPU 15 heures passé en code noyau, mesuré en jiffies 
 16 temps CPU cutime passé en code utilisateur , y compris le temps des enfants 
 17 cstime Temps processeur passé dans le code du noyau, y compris le temps des enfants 
 22 starttime Heure à laquelle le processus a démarré, mesurée en jiffies 

A jiffie est un tic d'horloge. Donc, en plus, il utilise diverses méthodes, c'est-à-dire., sysconf(_SC_CLK_TCK), pour obtenir le Hertz du système (nombre de ticks par seconde) - en utilisant finalement 100 comme solution de rechange après avoir épuisé d'autres options.

Donc si utime est 1234 et Hertz est 100 alors:

seconds = utime / Hertz = 1234 / 100 = 12.34

Le calcul proprement dit se fait par:

total_time = utime + stime

IF include_dead_children
    total_time = total_time + cutime + cstime
ENDIF

seconds = uptime - starttime / Hertz

pcpu = (total_time * 1000 / Hertz) / seconds

print: "%CPU" pcpu / 10 "." pcpu % 10

Exemple (sortie d'un script Bash personnalisé):

$ ./psw2 30894
System information
           uptime : 353,512 seconds
             idle : 0
Process information
              PID : 30894
         filename : plugin-containe
            utime : 421,951 jiffies 4,219 seconds
            stime : 63,334 jiffies 633 seconds
           cutime : 0 jiffies 0 seconds
           cstime : 1 jiffies 0 seconds
        starttime : 32,246,240 jiffies 322,462 seconds

Process run time  : 31,050
Process CPU time  : 485,286 jiffies 4,852 seconds
CPU usage since birth: 15.6%

Calcul de "courant" charge avec ps

C'est un effort (un peu?) Loufoque mais OK. Essayons.

On pourrait utiliser les temps fournis par ps et calculer l'utilisation du processeur à partir de cela. En y réfléchissant, cela pourrait être plutôt utile, avec certaines limites.

Cela peut être utile pour calculer l'utilisation du processeur sur une période plus longue. C'est à dire. dites que vous souhaitez surveiller la charge CPU moyenne de plugin-container dans Firefox tout en effectuant une tâche liée à Firefox.

En utilisant la sortie de:

$ ps -p -o cputime, etimes

CODE    HEADER   DESCRIPTION
cputime TIME     cumulative CPU time, "[DD-]hh:mm:ss" format.  (alias time).
etime   ELAPSED  elapsed time since the process was started, [DD-]hh:]mm:ss.
etimes  ELAPSED  elapsed time since the process was started, in seconds.

J'utilise etime sur etimes dans cet exemple, sur les calculs, pour être un peu plus clair. J'ajoute également% cpu pour "fun". Dans un script bash, on utiliserait évidemment etimes - ou mieux lire à partir de /proc/<PID>/ Etc.

Start:
$ ps -p 30894 -o %cpu,cputime,etime,etimes
%CPU     TIME     ELAPSED ELAPSED
 5.9 00:13:55    03:53:56   14036

End:
%CPU     TIME     ELAPSED ELAPSED
 6.2 00:14:45    03:56:07   14167

Calculate times:
            13 * 60 + 55 =    835   (cputime this far)
3 * 3,600 + 53 * 60 + 56 = 14,036   (time running this far)

            14 * 60 + 45 =    885   (cputime at end)
3 * 3,600 + 56 * 60 +  7 = 14,167   (time running at end)

Calculate percent load:
((885 - 835) / (14,167 - 14,036)) * 100 = 38

Le processus utilisait le CPU 38% du temps pendant cette période.

Regardez le code

Si vous voulez savoir comment ps le fait, et connaissez un peu C, faites (on dirait que vous exécutez Gnome Debain deriavnt) - Belle attitude dans le code concernant les commentaires etc:

apt-get source procps
cd procps*/ps
vim HACKING
89
Runium
man top

%CPU  --  CPU usage
The  task's share of the elapsed CPU time since the last screen update, expressed as a percentage of total CPU time.  In a true SMP environment, if 'Irix
mode' is Off, top will operate in 'Solaris mode' where a task's cpu usage will be divided by the total number of CPUs.  You toggle  'Irix/Solaris'  modes
with the 'I' interactive command.


man ps 
%cpu       %CPU    cpu utilization of the process in "##.#" format. Currently, it is the CPU time used divided by the time the process has been running                       (cputime/realtime ratio), expressed as a percentage. It will not add up to 100% unless you are lucky. (alias pcpu).
4
Rahul Patil