it-swarm.com.de

Wie erhalte ich die Gesamt-CPU-Auslastung einer Anwendung aus / proc / pid / stat?

Ich habe mich gefragt, wie man die gesamte CPU-Auslastung eines Prozesses berechnet.

Wenn ich mache cat /proc/pid/stat, Ich denke die relevanten Felder sind ( von lindevdoc.org genommen ):

  1. CPU-Zeit im Benutzercode, gemessen in Sekundenschnelle
  2. CPU-Zeit im Kernel-Code, gemessen in Sekundenschnelle
  3. CPU-Zeit im Benutzercode, einschließlich der Zeit von Kindern
  4. CPU-Zeit im Kernel-Code, einschließlich der Zeit von Kindern

Ist die Gesamtzeit also die Summe der Felder 14 bis 17?

52
user435739

Vorbereitung

Um die CPU-Auslastung für einen bestimmten Prozess zu berechnen, benötigen Sie Folgendes:

  1. /proc/uptime
    • #1 Betriebszeit des Systems (Sekunden)
  2. /proc/[PID]/stat
    • #14utime - CPU-Zeit, die im Benutzercode verbraucht wurde, gemessen in Clock Ticks
    • #15stime - CPU-Zeit im Kernel-Code, gemessen in Uhr-Ticks
    • #16cutime - Warte auf die CPU-Zeit von Kindern , die im Benutzercode verbracht wurde (in Uhr tickt)
    • #17cstime - Warte auf die CPU-Zeit von Kindern , die im Kernel-Code verbracht wurde (in Uhr tickt)
    • #22starttime - Zeitpunkt, zu dem der Prozess gestartet wurde, gemessen in Uhr-Ticks
  3. Hertz (Anzahl der Taktimpulse pro Sekunde) Ihres Systems.
    • In den meisten Fällen kann getconf CLK_TCK verwendet werden, um die Anzahl der Taktstriche zurückzugeben.
    • Der Funktionsaufruf sysconf(_SC_CLK_TCK) C kann auch verwendet werden, um den Hertz-Wert zurückzugeben.

Berechnung

Zuerst bestimmen wir die Gesamtzeit, die für den Prozess aufgewendet wurde:

total_time = utime + stime

Wir müssen uns auch entscheiden, ob wir die Zeit aus Kinderprozessen mit einbeziehen wollen. In diesem Fall fügen wir diese Werte zu total_time Hinzu:

total_time = total_time + cutime + cstime

Als nächstes erhalten wir die gesamte verstrichene Zeit in Sekunden seit Beginn des Prozesses:

seconds = uptime - (starttime / Hertz)

Schließlich berechnen wir den Prozentsatz der CPU-Auslastung:

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

Siehe auch

Top und ps zeigen nicht dasselbe CPU-Ergebnis

So erhalten Sie die vollständige CPU-Auslastung unter Linux (c ++)

Berechnung der CPU-Auslastung eines Prozesses unter Linux

120
Vilhelm Gray

Ja, das kannst du sagen. Sie können diese Werte mit folgender Formel in Sekunden umrechnen:

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

Der HZ-Wert ist konfigurierbar - wird zum Zeitpunkt der Kernelkonfiguration durchgeführt.

6
rakib_

Wenn Sie berechnen müssen, wie viel CPU% in den letzten 10 Sekunden von einem Prozess verbraucht wurde

  1. get total_time (13 + 14) in Sekunden => t1 starttime (22) in Sekunden => s1

- Verzögerung von 10 Sekunden

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

t2-t1 * 100/s2 - s1 würde nicht die% ??

3
user435739

Hier ist eine andere Möglichkeit, die CPU-Auslastung meiner App zu ermitteln. Ich habe dies in Android getan, und es wird ein Kernel-Top-Aufruf durchgeführt und die CPU-Auslastung für Ihre Apps-PID anhand der Top-Renditen ermittelt.

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;
}
2
GR Envoy

Hier ist meine einfache Lösung geschrieben in [~ # ~] bash [~ # ~]. Es ist ein Linux/Unix-Systemmonitor und Prozessmanager durch procfs, wie " top" oder " ps". Es gibt zwei Versionen, eine einfache monochrome (schnell) und eine farbige Version (etwas langsam, aber vor allem für die Überwachung des Status von Prozessen nützlich). Ich habe nach CPU-Auslastung sortiert.

https://github.com/AraKhachatryan/top

  • utime, stime, cutime, cstime, starttime wird verwendet, um cpu usage zu erhalten und wird aus /proc/[pid]/stat file bezogen.

  • state, ppid, priority, nice, num_threads Parameter erhalten Sie auch aus /proc/[pid]/stat Datei.

  • resident und data_and_stack Parameter, die zum Abrufen von memory usage verwendet werden und von /proc/[pid]/statm Datei.


    function my_ps
    {
        pid_array=`ls /proc | grep -E '^[0-9]+$'`
        clock_ticks=$(getconf CLK_TCK)
        total_memory=$( grep -Po '(?<=MemTotal:\s{8})(\d+)' /proc/meminfo )

        cat /dev/null > .data.ps

        for pid in $pid_array
        do
            if [ -r /proc/$pid/stat ]
            then
                stat_array=( `sed -E 's/(\([^\s)]+)\s([^)]+\))/\1_\2/g' /proc/$pid/stat` )
                uptime_array=( `cat /proc/uptime` )
                statm_array=( `cat /proc/$pid/statm` )
                comm=( `grep -Po '^[^\s\/]+' /proc/$pid/comm` )
                user_id=$( grep -Po '(?<=Uid:\s)(\d+)' /proc/$pid/status )

                user=$( id -nu $user_id )
                uptime=${uptime_array[0]}

                state=${stat_array[2]}
                ppid=${stat_array[3]}
                priority=${stat_array[17]}
                Nice=${stat_array[18]}

                utime=${stat_array[13]}
                stime=${stat_array[14]}
                cutime=${stat_array[15]}
                cstime=${stat_array[16]}
                num_threads=${stat_array[19]}
                starttime=${stat_array[21]}

                total_time=$(( $utime + $stime ))
                #add $cstime - CPU time spent in user and kernel code ( can olso add $cutime - CPU time spent in user code )
                total_time=$(( $total_time + $cstime ))
                seconds=$( awk 'BEGIN {print ( '$uptime' - ('$starttime' / '$clock_ticks') )}' )
                cpu_usage=$( awk 'BEGIN {print ( 100 * (('$total_time' / '$clock_ticks') / '$seconds') )}' )

                resident=${statm_array[1]}
                data_and_stack=${statm_array[5]}
                memory_usage=$( awk 'BEGIN {print( (('$resident' + '$data_and_stack' ) * 100) / '$total_memory'  )}' )

                printf "%-6d %-6d %-10s %-4d %-5d %-4s %-4u %-7.2f %-7.2f %-18s\n" $pid $ppid $user $priority $Nice $state $num_threads $memory_usage $cpu_usage $comm >> .data.ps

            fi
        done

        clear
        printf "\e[30;107m%-6s %-6s %-10s %-4s %-3s %-6s %-4s %-7s %-7s %-18s\e[0m\n" "PID" "PPID" "USER" "PR" "NI" "STATE" "THR" "%MEM" "%CPU" "COMMAND"
        sort -nr -k9 .data.ps | head -$1
        read_options
    }

screenshot of working script

0
Ara