Abfragen der idle zeit des rechners mit python ?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Mad-Marty
User
Beiträge: 317
Registriert: Mittwoch 18. Januar 2006, 19:46

Abfragen der idle zeit des rechners mit python ?

Beitragvon Mad-Marty » Donnerstag 26. Januar 2006, 09:27

Hallo,

hat schon jemand mal die systemlast abgefragt um z.b. einen Graph zu malen ?

Wenn ja, wie geht das ?

(irgendwelche externen kommandos nützen mir leider nichts)

Danke schonmal.
modelnine
User
Beiträge: 670
Registriert: Sonntag 15. Januar 2006, 18:42
Wohnort: Celle
Kontaktdaten:

Beitragvon modelnine » Donnerstag 26. Januar 2006, 10:04

Unter Linux:

Code: Alles auswählen

import time

def getidle(cpu=""):
    f = open("/proc/stat")
    for l in f:
        l = l.split()
        if l[0] == "cpu"+cpu:
            break
    return int(l[4])

def idle(cpu=""):
    idle1 = getidle(cpu)
    time.sleep(1)
    idle2 = getidle(cpu)
    return (idle2-idle1)/100.0


Zur Erklärung: getidle() liefert die Anzahl jiffies (hundertstel Sekunden) zurück, die das System (bzw. eine bestimmte CPU des Systems, angefangen mit der Nummerierung bei "0") sich im idle-Zustand befunden hat. Wir pausieren mit time.sleep() für eine Sekunde, messen den Unterschied zwischen den beiden Idle-Werten, und kriegen somit eine Zahl die beschreibt wieviele hundertstel Sekunden sich die CPU in der letzten Sekunde im Leerlauf befunden hat. Diese Zahl teilt man durch hundert, und bekommt eine Zahl wieviel Zeit der letzten Sekunde Leerlauf war. Das ist genau die Prozentzahl die man wissen will.

Anmerkung: Das obige Script probiert für Multi-CPU-Systeme gar nicht erst den richtigen Wert zu berechnen, da man dann idle() noch durch die Anzahl der Prozessoren teilen muß (cpu beschreibt die Gesamtzahl der jiffies die sich alle CPUs zusammen im idle-modus befunden haben, ist also doppelt so groß bei zwei CPUs, usw.). Die Anzahl der Prozessoren aus /proc/stat rauszufinden ist weiter kein Problem; siehe cat /proc/stat, nur überlass ich das dem Leser.

Unter Windows und anderen Unix-Varianten: keine Ahnung, obwohl /proc/stat relativ genormt ist zwischen Unix-artigen Systemen (also nicht Windows!). Für eine ausführlichere Erklärung von /proc/stat kann ich nur man proc empfehlen.

--- Heiko.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5554
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Telfs (Tirol)
Kontaktdaten:

Re: Abfragen der idle zeit des rechners mit python ?

Beitragvon gerold » Donnerstag 26. Januar 2006, 10:27

Mad-Marty hat geschrieben:hat schon jemand mal die systemlast abgefragt um z.b. einen Graph zu malen ?

Hi Mad-Marty!

Für Windows:

Dass es ein externes Kommandozeilentool dafür gibt, dass weiß ich sicher. Ich müsste mal nachsehen wie es heißt. Es ist, glaube ich, beim Platform SDK dabei.

Es gibt einen unsichtbaren Registry-Key, den man abfragen kann. Allerdings weiß ich nicht ob dabei auch die gewünschten Daten raus kommen.

HKEY_PERFORMANCE_DATA

Link1
Link2
Link3

Allerdings habe ich es noch nie versucht, diesen Key mit Python abzufragen. Vielleicht genügt es ja schon, den Wert der Konstante (falls es eine ist) auszuforschen und zu benützen.

mfg
Gerold
:-)
Zuletzt geändert von gerold am Donnerstag 26. Januar 2006, 11:50, insgesamt 1-mal geändert.
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Mad-Marty
User
Beiträge: 317
Registriert: Mittwoch 18. Januar 2006, 19:46

Beitragvon Mad-Marty » Donnerstag 26. Januar 2006, 11:47

ich habe eben das gefunden :

Windows Only natürlich ;)

EDIT: So, nachdem ich ctypes hab, läuft das auch und zeigt mir alle prozesse, jetzt versuche ich krampfhaft herauszufinden wie ich die cpu last sehen kann ....








Title: getting process information on windows
Submitter: Eric Koome (other recipes)
Last Updated: 2004/09/22
Version no: 1.3
Category:



Not Rated yet

Description:

This recipe will enumerate active processes as seen under windows Task Manager on Win NT/2k/XP using PSAPI.dll (new api for processes) and using ctypes.
Use it as you please

Source: Text Source

Code: Alles auswählen

"""
Enumerates active processes as seen under windows Task Manager on Win NT/2k/XP using PSAPI.dll
(new api for processes) and using ctypes.Use it as you please.

Based on information from http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q175030&ID=KB;EN-US;Q175030

By Eric Koome
email ekoome@yahoo.com
license GPL
"""
from ctypes import *

#PSAPI.DLL
psapi = windll.psapi
#Kernel32.DLL
kernel = windll.kernel32

def EnumProcesses():
    arr = c_ulong * 256
    lpidProcess= arr()
    cb = sizeof(lpidProcess)
    cbNeeded = c_ulong()
    hModule = c_ulong()
    count = c_ulong()
    modname = c_buffer(30)
    PROCESS_QUERY_INFORMATION = 0x0400
    PROCESS_VM_READ = 0x0010
   
    #Call Enumprocesses to get hold of process id's
    psapi.EnumProcesses(byref(lpidProcess),
                        cb,
                        byref(cbNeeded))
   
    #Number of processes returned
    nReturned = cbNeeded.value/sizeof(c_ulong())
   
    pidProcess = [i for i in lpidProcess][:nReturned]
   
    for pid in pidProcess:
       
        #Get handle to the process based on PID
        hProcess = kernel.OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
                                      False, pid)
        if hProcess:
            psapi.EnumProcessModules(hProcess, byref(hModule), sizeof(hModule), byref(count))
            psapi.GetModuleBaseNameA(hProcess, hModule.value, modname, sizeof(modname))
            print "".join([ i for i in modname if i != '\x00'])
           
            #-- Clean up
            for i in range(modname._length_):
                modname[i]='\x00'
           
            kernel.CloseHandle(hProcess)

if __name__ == '__main__':
    EnumProcesses()
Mad-Marty
User
Beiträge: 317
Registriert: Mittwoch 18. Januar 2006, 19:46

Beitragvon Mad-Marty » Donnerstag 26. Januar 2006, 16:30

modelnine hat geschrieben:Unter Linux:

Code: Alles auswählen

import time

def getidle(cpu=""):
    f = open("/proc/stat")
    for l in f:
        l = l.split()
        if l[0] == "cpu"+cpu:
            break
    return int(l[4])

def idle(cpu=""):
    idle1 = getidle(cpu)
    time.sleep(1)
    idle2 = getidle(cpu)
    return (idle2-idle1)/100.0


Zur Erklärung: getidle() liefert die Anzahl jiffies (hundertstel Sekunden) zurück, die das System (bzw. eine bestimmte CPU des Systems, angefangen mit der Nummerierung bei "0") sich im idle-Zustand befunden hat. Wir pausieren mit time.sleep() für eine Sekunde, messen den Unterschied zwischen den beiden Idle-Werten, und kriegen somit eine Zahl die beschreibt wieviele hundertstel Sekunden sich die CPU in der letzten Sekunde im Leerlauf befunden hat. Diese Zahl teilt man durch hundert, und bekommt eine Zahl wieviel Zeit der letzten Sekunde Leerlauf war. Das ist genau die Prozentzahl die man wissen will.

Anmerkung: Das obige Script probiert für Multi-CPU-Systeme gar nicht erst den richtigen Wert zu berechnen, da man dann idle() noch durch die Anzahl der Prozessoren teilen muß (cpu beschreibt die Gesamtzahl der jiffies die sich alle CPUs zusammen im idle-modus befunden haben, ist also doppelt so groß bei zwei CPUs, usw.). Die Anzahl der Prozessoren aus /proc/stat rauszufinden ist weiter kein Problem; siehe cat /proc/stat, nur überlass ich das dem Leser.

Unter Windows und anderen Unix-Varianten: keine Ahnung, obwohl /proc/stat relativ genormt ist zwischen Unix-artigen Systemen (also nicht Windows!). Für eine ausführlichere Erklärung von /proc/stat kann ich nur man proc empfehlen.

--- Heiko.



Hi, ich brauche fürs linux mehr hilfe - da das nicht unbedingt mein lieblings os ist ;)

was in /proc muss ich lesen um die cpu load in % für einen bestimmten prozess zu sehen ?

also /proc/<pid>/ ..???..

Und ist der overhead sehr gross wenn ich jede sekunde das da mache, weil das sind ja file-objects im ram, oder ?
Michael Janssen
User
Beiträge: 3
Registriert: Freitag 27. Januar 2006, 15:55

Beitragvon Michael Janssen » Freitag 27. Januar 2006, 16:34

Mad-Marty hat geschrieben:
Hi, ich brauche fürs linux mehr hilfe - da das nicht unbedingt mein lieblings os ist ;)

was in /proc muss ich lesen um die cpu load in % für einen bestimmten prozess zu sehen ?

also /proc/<pid>/ ..???..


/proc/<pid>/stat

Schwierig ist nur herauszufinden, welche hier die gesuchten Zahlen sind. Du brauchst vrmtl die user-jiffies (jiffies sind unter Linux aus historischen Gründen 100stel Sekunden, während die CPU seit kernel 2.6 mit 1000stel timeslices betrieben wird. Das Gute daran ist, dass man zu Prozentangaben nicht wissen braucht, was genau ein jiffy ist). Die user Zeit wird dann gegen die user+system+nice+idle jiffies des System (aus /proc/stat) gegengerechnet und heraus kommt ein Wert der evt aussagekräftig ist. Sowohl System- als auch Prozess-jiffies müssen natürlich die Differenz zweier Durchläufe im sinnvollen Zeitabstand sein.

Ich habe vor langer Zeit einmal in mühevoller Kleinarbeit eine Liste der Namen für die Zahlen in /proc/<pid>/stat herausgeschrieben:

Code: Alles auswählen

def proc_pid_stat_names(values):
    names = ["pid", "comm", "state", "ppid", "pid",
             "pgrp", "session", "tty_nr", "tpgid",
             "flags", "minflt", "cminflt", "majflt",
             "cmajflt", "utime", "stime", "cutime",
             "cstime", "priority", "nice", "zero",
             "itrealvalue", "starttime", "vsize",
             "rss", "rlim", "startcode", "endcode",
             "startstack", "kstkesp", "kstkeip",
             "signal", "blocked", "sigignore",
             "sigcatch", "wchan", "nswap", "cnswap",
             "exit_signal", "processor"]
    maxName = max([len(name) for name in names])
    maxValue = max([len(value) for value in values])
    i = 0
    for name, value in map(None, names, values):
        print "%2s %*s: %*s" % (i, maxName, name, maxValue, value)
        i += 1

import sys
fs = file("/proc/%s/stat" % sys.argv[1]).read()
values = fs.split()
proc_pid_stat_names(values)


vgl zu diesen Namen "man proc". Ich würde also sagen, dass ein

Code: Alles auswählen

fs = file("/proc/%s/stat" % sys.argv[1]).read()
utime = fs.split()[14]


schon recht gut ist.

Grüße
Michael
Mad-Marty
User
Beiträge: 317
Registriert: Mittwoch 18. Januar 2006, 19:46

Beitragvon Mad-Marty » Freitag 27. Januar 2006, 22:24

Danke, sehr wertvolle Antwort.

user+system+nice+idle jiffies

= utime, stime, cutime, cstime ???


Auserdem frage ich mich was ein nice jiffie sein soll ...
Ich kenne eigentlich nur usertime, kerneltime(systime), wait, idle.

Das ich 2 mal alle Werte holen muss für die differenz erscheint logisch, ist btw bei dem windows call genauso.
Michael Janssen
User
Beiträge: 3
Registriert: Freitag 27. Januar 2006, 15:55

Beitragvon Michael Janssen » Sonntag 29. Januar 2006, 20:54

Mad-Marty hat geschrieben:Danke, sehr wertvolle Antwort.

user+system+nice+idle jiffies

= utime, stime, cutime, cstime ???



nein. Schau in "man proc" nach. Eher user, szstem, child-user, child-system


Auserdem frage ich mich was ein nice jiffie sein soll ...
Ich kenne eigentlich nur usertime, kerneltime(systime), wait, idle.


ich kenne wait nicht. Nice ist Rechenzeit von Prozessen mit niedriger Prioritaet ("nice" gegenueber anderen).

Gruesse
Michael
Mad-Marty
User
Beiträge: 317
Registriert: Mittwoch 18. Januar 2006, 19:46

Beitragvon Mad-Marty » Montag 30. Januar 2006, 12:19

Michael Janssen hat geschrieben:
Mad-Marty hat geschrieben:Danke, sehr wertvolle Antwort.

user+system+nice+idle jiffies

= utime, stime, cutime, cstime ???



nein. Schau in "man proc" nach. Eher user, szstem, child-user, child-system


Auserdem frage ich mich was ein nice jiffie sein soll ...
Ich kenne eigentlich nur usertime, kerneltime(systime), wait, idle.


ich kenne wait nicht. Nice ist Rechenzeit von Prozessen mit niedriger Prioritaet ("nice" gegenueber anderen).

Gruesse
Michael



Hi Michael,
man proc gibts nicht - bzw ich glaube nicht das "proc - Create a TCL procedure" das richtige ist .... :(

Das mein ich, mit praktisch undokumentiert ;-).

Also sind es die 4 da unten ?



["pid", "comm", "state", "ppid", "pid",
"pgrp", "session", "tty_nr", "tpgid",
"flags", "minflt", "cminflt", "majflt",
"cmajflt", "utime", "stime", "cutime",
"cstime", "priority", "nice", "zero",
"itrealvalue", "starttime", "vsize",
"rss", "rlim", "startcode", "endcode",
"startstack", "kstkesp", "kstkeip",
"signal", "blocked", "sigignore",
"sigcatch", "wchan", "nswap", "cnswap",
"exit_signal", "processor"]


Vielen Dank
modelnine
User
Beiträge: 670
Registriert: Sonntag 15. Januar 2006, 18:42
Wohnort: Celle
Kontaktdaten:

Beitragvon modelnine » Montag 30. Januar 2006, 13:12

Man proc gibt es sehr wohl, dann hat Deine Linux-Distro das nicht standardmäßig mitinstalliert (böse!).

Folgende URL sollte Aufklärung bringen:

http://blog.modelnine.org/2006/01/30/proc-manpage

--- Heiko.
Mad-Marty
User
Beiträge: 317
Registriert: Mittwoch 18. Januar 2006, 19:46

Beitragvon Mad-Marty » Montag 30. Januar 2006, 15:15

Danke modelnine für die man pages.

Bei mir :
Die distro ist SuSe 10

und bei man proc kommt halt das da unten. aber jetzt hab ichs ja von dir :)

Code: Alles auswählen

proc(n)                                                  Tcl Built-In Commands                                                 proc(n)



______________________________________________________________________________________________________________________________________

NAME
       proc - Create a Tcl procedure

SYNOPSIS
       proc name args body
______________________________________________________________________________________________________________________________________


DESCRIPTION
       The  proc  command  creates  a new Tcl procedure named name, replacing any existing command or procedure there may have been by
       that name.  Whenever the new command is invoked, the contents of body will be executed by the Tcl interpreter.  Normally,  name
       is  unqualified  (does  not  include  the  names of any containing namespaces), and the new procedure is created in the current
       namespace.  If name includes any namespace qualifiers, the procedure is created in the specified namespace.  Args specifies the
       formal arguments to the procedure.  It consists of a list, possibly empty, each of whose elements specifies one argument.  Each
       argument specifier is also a list with either one or two fields.  If there is only a single field in the specifier then  it  is
       the name of the argument; if there are two fields, then the first is the argument name and the second is its default value.

       When  name is invoked a local variable will be created for each of the formal arguments to the procedure; its value will be the
       value of corresponding argument in the invoking command or the argument's default value.  Arguments with  default  values  need
       not  be  specified in a procedure invocation.  However, there must be enough actual arguments for all the formal arguments that
       don't have defaults, and there must not be any extra actual arguments.  There is one special case  to  permit  procedures  with
       variable  numbers  of  arguments.  If the last formal argument has the name args, then a call to the procedure may contain more
       actual arguments than the procedure has formals.  In this case, all of the actual arguments starting at the one that  would  be
       assigned  to args are combined into a list (as if the list command had been used); this combined value is assigned to the local
       variable args.

usw usw
modelnine
User
Beiträge: 670
Registriert: Sonntag 15. Januar 2006, 18:42
Wohnort: Celle
Kontaktdaten:

Beitragvon modelnine » Montag 30. Januar 2006, 15:27

Probier mal:

Code: Alles auswählen

man 5 proc


Ich hab von jemandem anderes gehört dass SuSE sehr wohl die Man-Page mitliefert, Du kriegst aber eben die Manpage aus Sektion n angezeigt, während halt proc in Sektion 5 ist (Namen können überlappen, nur in einer Sektion halt eben nicht).

Sehr hilfreiches Tool hierzu ist apropos:

Code: Alles auswählen

apropos proc


liefert Dir alle Manpages die irgendwas mit dem Stichwort proc zu tun haben.

--- Heiko.

Wer ist online?

Mitglieder in diesem Forum: Majestic-12 [Bot]