Top e ps non mostrano lo stesso risultato della CPU


54

Questo è collegato a questa domanda.

Quando corro topottengo il seguente risultato:

inserisci qui la descrizione dell'immagine

pid 3038utilizza il 18% di CPU, tuttavia durante l'esecuzione

inserisci qui la descrizione dell'immagine

il risultato è del 5,5%. E questo numero non sembra cambiare con il tempo (cioè quando si esegue lo stesso comando un po 'più tardi) ...

Il pscomando sta in qualche modo calcolando la media dell'utilizzo della CPU?

Risposte:


87

man psnella NOTESsezione.

   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%.

E, indovina, lo sai, ma puoi anche fare:

top -p <PID>

Modifica : quanto al tuo commento su un'altra risposta;

" Hmm, sì, mi chiedo come ottenerlo (la percentuale di CPU istantanea) da ps "

Risposta breve: non puoi.

Perché è così?

È come chiedere a qualcuno di calcolare la velocità di un'auto da una foto.

Mentre topè uno strumento di monitoraggio, psè uno strumento di istantanea. Pensala in questo modo: in un dato momento un processo utilizza la CPU o no. In questo momento, hai un carico dello 0% o del 100% in quel preciso momento.

Dare: se psdovesse dare un utilizzo istantaneo della CPU sarebbe 0% o 100%.

top d'altra parte mantenere i numeri di polling e calcolare il carico nel tempo.

psavrebbe potuto fornire l'utilizzo corrente, ma ciò richiederebbe che leggesse i dati più volte e dormisse tra una lettura e l'altra. Non

Calcolo per ps% cpu

ps calcola l'utilizzo della CPU nel modo seguente:

uptime = tempo totale di funzionamento del sistema.
ps_time = tempo di avvio del processo misurato in secondi dall'avvio.
pu_time = il processo di tempo totale utilizza la CPU.

;; Il processo dei secondi è in esecuzione:
secondi = uptime - ps_time
;; Uso:
cpu_usage = pu_time * 1000 / secondi

stampa: cpu_usage / 10 "." cpu_usage% 10


Esempio: tempo di attività = 344.545 ps_time = 322.462 pu_time = 3.383 secondi = 344.545 - 322.462 = 22.083 cpu_usage = 3.383 * 1.000 / 22.083 = 153 stampa: 153/10 "." 153% 10 => 15.3

Quindi il numero stampato è: tempo in cui il processo ha utilizzato la CPU durante la sua vita. Come nell'esempio sopra. Lo ha fatto nel 15,3% della sua vita. Nell'84,7% delle volte non si è verificato un errore nella CPU.

Recupero dei dati

ps, nonché top, utilizza i dati dei file archiviati in /proc/- o il pseudo-file system delle informazioni di processo .

Hai alcuni file nella radice /proc/che contengono varie informazioni sullo stato generale del sistema. Inoltre ogni processo ha la sua sottocartella in /proc/<PID>/cui sono memorizzati i dati specifici del processo. Quindi, ad esempio, il processo della tua domanda aveva una cartella in /proc/3038/.

Quando pscalcola l'utilizzo della CPU utilizza due file:

/ proc / uptime Il tempo di attività del sistema (secondi) e la quantità di tempo impiegata nel processo inattivo (secondi).
/ proc / [PID] / stat Informazioni sullo stato del processo.
  • Da uptimeesso utilizza il primo valore ( uptime ).
  • Da [PID]/statesso utilizza quanto segue:
 # Nome Descrizione
14 tempo CPU utime trascorso nel codice utente, misurato in jiffies
15 stime di tempo CPU trascorso nel codice del kernel, misurato in jiffies
16 cutime CPU time spesi nel codice utente, incluso il tempo dei bambini
17 cstime Tempo della CPU trascorso nel codice del kernel, incluso il tempo dei bambini 
22 starttime Ora di inizio del processo, misurata in jiffies

Un batter d'occhio è il ticchettio dell'orologio. Quindi, inoltre, utilizza vari metodi, ad es., sysconf(_SC_CLK_TCK)Per ottenere l'Hertz del sistema (numero di tick al secondo), usando infine 100 come fallback dopo aver esaurito altre opzioni.

Quindi se utimeè 1234 e Hertz è 100, allora:

seconds = utime / Hertz = 1234 / 100 = 12.34

Il calcolo effettivo viene eseguito da:

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

Esempio (output da uno script Bash personalizzato):

$ ./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%

Calcolo del carico "corrente" con ps

Questo è uno sforzo (un po '?) Losco ma OK. Proviamo.

Si potrebbero usare i tempi forniti pse calcolare l'utilizzo della CPU da questo. Pensandoci potrebbe effettivamente essere piuttosto utile, con alcune limitazioni.

Ciò potrebbe essere utile per calcolare l'utilizzo della CPU per un periodo più lungo. Vale a dire che si desidera monitorare il carico medio della CPU plugin-containerin Firefox mentre si esegue un'attività correlata a Firefox.

Utilizzando l'output di:

$ 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.

Io uso etimesopra etimesin questo campione, su calcoli, solo per essere un po 'più chiaro. Inoltre aggiungo% cpu per "divertimento". Ovviamente in uno script bash si userebbe ovviamente etimes- o meglio leggere da /proc/<PID>/ecc.

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

Durante questo periodo il processo utilizzava la CPU il 38% delle volte.

Guarda il codice

Se vuoi sapere come psfa, e sapere un po 'di C, fallo (sembra che tu esegua Gnome Debain deriavnt) - bel atteggiamento nel codice riguardo ai commenti ecc .:

apt-get source procps
cd procps*/ps
vim HACKING

Potrei aggiornare con ulteriori informazioni tope monitoraggio continuo - o scattare in ritardo, noto anche come " ps" con il carico della CPU corrente.
Runium

2
Davvero un'ottima risposta!
Theodor il

Che dire del calcolo dell'utilizzo totale della CPU nell'intero sistema? Gli strumenti stanno cercando di ottenere l'utilizzo della CPU tramite un'istantanea o di farne una media nel tempo?
CMCDragonkai,

4
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).

Hmm, sì, mi chiedo come ottenerlo (la percentuale di CPU istantanea) daps
Theodor il

2
puoi estrarre dall'esempio principaletop -p 3343 -n1 | awk '/ R /{print $10}'
Rahul Patil,

1
Eccezionale. Ho scoperto che awk: ing per il pidfunzionava meglio, come intop -p 3343 -n1 | awk '/ 3343 /{print $10}'
Theodor il

1
Grazie "top -p" è carino, non ho mai notato questa opzione! Tuttavia, non mi piace cercare il PID, cosa succede se per caso le stesse cifre appaiono nella sezione di memoria libera o qualcosa del genere. Sul mio sistema le informazioni sono nell'ottava riga e nella nona colonna, quindi lo faccio:top -p $PID -n1 | awk '{if (NR ==8) print $9 }'
phil_w,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.