Come posso ottenere l’utilizzo totale della CPU di un’applicazione da / proc / pid / stat?

Mi chiedevo come calcolare l’utilizzo totale della CPU di un processo.

Se faccio cat /proc/ pid /stat , penso che i campi rilevanti siano ( presi da lindevdoc.org ):

  1. Tempo di CPU speso nel codice utente, misurato in jiffies
  2. Tempo di CPU speso nel codice del kernel, misurato in jiffies
  3. Tempo di CPU trascorso nel codice utente, incluso il tempo trascorso dai bambini
  4. Tempo della CPU trascorso nel codice del kernel, incluso il tempo trascorso dai bambini

Quindi il tempo totale spende la sum dei campi da 14 a 17?

Preparazione

Per calcolare l’utilizzo della CPU per un processo specifico è necessario quanto segue:

  1. /proc/uptime
    • #1 uptime del sistema (secondi)
  2. /proc/[PID]/stat
    • #14 utime : tempo impiegato dalla CPU nel codice utente, misurato in tick di clock
    • #15 stime : tempo di CPU speso nel codice del kernel, misurato in tick di clock
    • #16 cutime – Tempo CPU atteso per bambini speso nel codice utente (in tick dell’orologio )
    • #17 cstimecstime della CPU dei bambini atteso speso nel codice del kernel (in tick dell’orologio )
    • #22 starttime – Tempo in cui il processo è iniziato, misurato in tick di clock
  3. Hertz (numero di zecche dell’orologio al secondo) del sistema.
    • Nella maggior parte dei casi, è ansible utilizzare getconf CLK_TCK per restituire il numero di getconf CLK_TCK di clock.
    • La chiamata di funzione sysconf(_SC_CLK_TCK) C può essere utilizzata anche per restituire il valore di hertz.

Calcolo

Per prima cosa determiniamo il tempo totale speso per il processo:

 total_time = utime + stime 

Dobbiamo anche decidere se vogliamo includere il tempo dai processi figli. Se lo facciamo, aggiungiamo quei valori a total_time :

 total_time = total_time + cutime + cstime 

Successivamente otteniamo il tempo trascorso totale in secondi dall’inizio del processo:

 seconds = uptime - (starttime / Hertz) 

Infine calcoliamo la percentuale di utilizzo della CPU:

 cpu_usage = 100 * ((total_time / Hertz) / seconds) 

Guarda anche

Top e ps non mostrano lo stesso risultato della CPU

Come ottenere l’utilizzo totale della CPU in Linux (c ++)

Calcolo dell’utilizzo della CPU di un processo in Linux

Sì, puoi dirlo. Puoi convertire quei valori in secondi usando la formula:

  sec = jiffies / HZ ; here - HZ = number of ticks per second 

Il valore HZ è configurabile, fatto al momento della configurazione del kernel.

Se è necessario calcolare la quantità di CPU utilizzata da un processo negli ultimi 10 secondi

  1. ottieni total_time (13 + 14) in jiffies => t1 starttime (22) in jiffies => s1

–delay di 10 secondi

total_time (13 + 14) in jiffies => t2 starttime (22) in jiffies => s2

t2-t1 * 100 / s2 – s1 non darebbe il% ??

Ecco un altro modo in cui ho ottenuto l’utilizzo della CPU della mia app. Ho fatto questo in Android, e fa una chiamata al top del kernel e ottiene l’utilizzo della CPU per le tue app PID usando i migliori ritorni.

 public void myWonderfulApp() { // Some wonderfully written code here Integer lMyProcessID = android.os.Process.myPid(); int lMyCPUUsage = getAppCPUUsage( lMyProcessID ); // More magic } // Alternate way that I switched to. I found the first version was slower // this version only returns a single line for the app, so far less parsing // and processing. public static float getTotalCPUUsage2() { try { // read global stats file for total CPU BufferedReader reader = new BufferedReader(new FileReader("/proc/stat")); String[] sa = reader.readLine().split("[ ]+", 9); long work = Long.parseLong(sa[1]) + Long.parseLong(sa[2]) + Long.parseLong(sa[3]); long total = work + Long.parseLong(sa[4]) + Long.parseLong(sa[5]) + Long.parseLong(sa[6]) + Long.parseLong(sa[7]); reader.close(); // calculate and convert to percentage return restrictPercentage(work * 100 / (float) total); } catch (Exception ex) { Logger.e(Constants.TAG, "Unable to get Total CPU usage"); } // if there was an issue, just return 0 return 0; } // This is an alternate way, but it takes the entire output of // top, so there is a fair bit of parsing. public static int getAppCPUUsage( Integer aAppPID) { int lReturn = 0; // make sure a valid pid was passed if ( null == aAppPID && aAppPID > 0) { return lReturn; } try { // Make a call to top so we have all the processes CPU Process lTopProcess = Runtime.getRuntime().exec("top"); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(lTopProcess.getInputStream())); String lLine; // While we have stuff to read and we have not found our PID, process the lines while ( (lLine = bufferedReader.readLine()) != null ) { // Split on 4, the CPU % is the 3rd field . // NOTE: We trim because sometimes we had the first field in the split be a "". String[] lSplit = lLine.trim().split("[ ]+", 4); // Don't even bother if we don't have at least the 4 if ( lSplit.length > 3 ) { // Make sure we can handle if we can't parse the int try { // On the line that is our process, field 0 is a PID Integer lCurrentPID = Integer.parseInt(lSplit[0]); // Did we find our process? if (aAppPID.equals(lCurrentPID)) { // This is us, strip off the % and return it String lCPU = lSplit[2].replace("%", ""); lReturn = Integer.parseInt(lCPU); break; } } catch( NumberFormatException e ) { // No op. We expect this when it's not a PID line } } } bufferedReader.close(); lTopProcess.destroy(); // Cleanup the process, otherwise you make a nice hand warmer out of your device } catch( IOException ex ) { // Log bad stuff happened } catch (Exception ex) { // Log bad stuff happened } // if there was an issue, just return 0 return lReturn; } 

Ecco cosa stai cercando:

 //USER_HZ detection, from openssl code #ifndef HZ # if defined(_SC_CLK_TCK) \ && (!defined(OPENSSL_SYS_VMS) || __CTRL_VER >= 70000000) # define HZ ((double)sysconf(_SC_CLK_TCK)) # else # ifndef CLK_TCK # ifndef _BSD_CLK_TCK_ /* FreeBSD hack */ # define HZ 100.0 # else /* _BSD_CLK_TCK_ */ # define HZ ((double)_BSD_CLK_TCK_) # endif # else /* CLK_TCK */ # define HZ ((double)CLK_TCK) # endif # endif #endif 

Questo codice è in realtà da cpulimit , ma utilizza snippet di openssl.