2008-09-09 36 views
5

Tengo una configuración Samurize que muestra un gráfico de uso de CPU similar al Administrador de tareas.Nombre del proceso con mayor uso de CPU

¿Cómo también visualizo el nombre del proceso con el porcentaje de uso de CPU más alto actual?

Me gustaría que esto se actualice, como máximo, una vez por segundo. Samurize puede llamar a una herramienta de línea de comando y mostrar su salida en pantalla, por lo que esta también podría ser una opción.


cualquier aclaración:

he investigado escribir mi propia aplicación de línea de comandos C# .NET para enumerar la matriz devuelta por System.Diagnostics.Process.GetProcesses(), pero no parece la clase de instancia de proceso para incluir una propiedad de porcentaje de CPU.

¿Puedo calcular esto de alguna manera?

+0

¿Es esta una pregunta acerca de cómo utilizar el paquete samurize? ¿Quizás podría reformular como una pregunta de programación? –

Respuesta

-3

Con PowerShell:

Get-Process | Sort-Object CPU -desc | Select-Object -first 3 | Format-Table CPU,ProcessName -hidetableheader 

vuelve algo así como:

16.8641632 System 
    12.548072 csrss 
    11.9892168 powershell 
+1

elimine el piope entre format-table y cpua – JJS

+8

también, claramente, la CPU no le da el porcentaje de la CPU utilizada. es el tiempo total del procesador en segundos que el proceso ha estado activo. powershell "get-process | get-member | Select-Object Name, Definition | sort-object Name | format-list" La CPU se define como {get = $ this.TotalProcessorTime.TotalSeconds;} – JJS

1

Puede ser que usted pueda usar Pmon.exe para esto. Puede obtenerlo como parte del Windows Resource Kit tools (el enlace es a la versión de Server 2003, que aparentemente también se puede usar en XP).

6

Lo que se quiere conseguir su uso de la CPU instantánea (tipo de) ...

En realidad, el uso de CPU instantáneo para un proceso no existe. En lugar de ello hay que hacer dos mediciones y calcular el promedio de uso de la CPU, la fórmula es bastante simple:

AvgCpuUsed = [TotalCPUTime (proceso, tiempo2) - TotalCPUTime (proceso, tiempo1)]/[tiempo2-tiempo1]

Cuanto menor es la diferencia de Time2 y Time1, más "instantánea" será su medición. El Administrador de tareas de Windows calcula el uso de la CPU con un intervalo de un segundo. He descubierto que es más que suficiente y que incluso podría considerar hacerlo en intervalos de 5 segundos porque el acto de medir en sí mismo requiere ciclos de CPU ...

Así, en primer lugar, para obtener el promedio de tiempo de CPU

using System.Diagnostics; 

float GetAverageCPULoad(int procID, DateTme from, DateTime, to) 
{ 
    // For the current process 
    //Process proc = Process.GetCurrentProcess(); 
    // Or for any other process given its id 
    Process proc = Process.GetProcessById(procID); 
    System.TimeSpan lifeInterval = (to - from); 
    // Get the CPU use 
    float CPULoad = (proc.TotalProcessorTime.TotalMilliseconds/lifeInterval.TotalMilliseconds) * 100; 
    // You need to take the number of present cores into account 
    return CPULoad/System.Environment.ProcessorCount; 
} 

ahora, para la carga de la CPU "instantánea" se necesita de una clase especializada:

class ProcLoad 
{ 
    // Last time you checked for a process 
    public Dictionary<int, DateTime> lastCheckedDict = new Dictionary<int, DateTime>(); 

    public float GetCPULoad(int procID) 
    { 
    if (lastCheckedDict.ContainsKey(procID)) 
    { 
     DateTime last = lastCheckedDict[procID]; 
     lastCheckedDict[procID] = DateTime.Now; 
     return GetAverageCPULoad(procID, last, lastCheckedDict[procID]); 
    } 
    else 
    { 
     lastCheckedDict.Add(procID, DateTime.Now); 
     return 0; 
    } 
    } 
} 

usted debe llamar a esa clase desde un temporizador (o el método de intervalo que desee) para cada proceso que desee controlar, si desea todos los procesos, simplemente utilice el Process.GetProcesses método estático

0

También puede hacerlo de esta manera: -

public Process getProcessWithMaxCPUUsage() 
    { 
     const int delay = 500; 
     Process[] processes = Process.GetProcesses(); 

     var counters = new List<PerformanceCounter>(); 

     foreach (Process process in processes) 
     { 
      var counter = new PerformanceCounter("Process", "% Processor Time", process.ProcessName); 
      counter.NextValue(); 
      counters.Add(counter); 
     } 
     System.Threading.Thread.Sleep(delay); 
     //You must wait(ms) to ensure that the current 
     //application process does not have MAX CPU 
     int mxproc = -1; 
     double mxcpu = double.MinValue, tmpcpu; 
     for (int ik = 0; ik < counters.Count; ik++) 
     { 
      tmpcpu = Math.Round(counters[ik].NextValue(), 1); 
      if (tmpcpu > mxcpu) 
      { 
       mxcpu = tmpcpu; 
       mxproc = ik; 
      } 

     } 
     return processes[mxproc]; 
    } 

Uso: -

static void Main() 
    { 
     Process mxp=getProcessWithMaxCPUUsage(); 
     Console.WriteLine(mxp.ProcessName); 
    } 
0

De alguna manera

Get-Process | Sort-Object CPU -desc | Select-Object -first 3 | Format-Table CPU,ProcessName,TotalProcessorTime -hidetableheader

no estaba recibiendo la información de la CPU de la máquina remota. Tenía que pensar en esto.

Get-Counter '\Process(*)\% Processor Time' | Select-Object -ExpandProperty countersamples | Select-Object -Property instancename, cookedvalue| Sort-Object -Property cookedvalue -Descending| Select-Object -First 10| ft -AutoSize

1

Gracias por la fórmula, Jorge. No entiendo muy bien por qué tienes que dividir por el número de núcleos, pero los números que obtengo coinciden con el Administrador de tareas. Aquí está mi código de PowerShell:

$procID = 4321 

$time1 = Get-Date 
$cpuTime1 = Get-Process -Id $procID | Select -Property CPU 

Start-Sleep -s 2 

$time2 = Get-Date 
$cpuTime2 = Get-Process -Id $procID | Select -Property CPU 

$avgCPUUtil = ($cpuTime2.CPU - $cpuTime1.CPU)/($time2-$time1).TotalSeconds *100/[System.Environment]::ProcessorCount 
+0

¡Gracias por el ejemplo de trabajo! Finalmente se dio cuenta de que la propiedad de la CPU era TotalSeconds del TotalProcessorTime para el proceso y que TotalSeconds solo está disponible como un objeto TimeSpan y no como un objeto DateTime. – RiverHeart

2

Sobre la base de la respuesta de Frederic y utilizando el código en la parte inferior de la página here (para un ejemplo de uso ver this post) para unirse a la totalidad de los procesos recibido de Get-Process, obtenemos lo siguiente:

$sampleInterval = 3 

$process1 = Get-Process |select Name,Id, @{Name="Sample1CPU"; Expression = {$_.CPU}} 

Start-Sleep -Seconds $sampleInterval 

$process2 = Get-Process | select Id, @{Name="Sample2CPU"; Expression = {$_.CPU}} 

$samples = Join-Object -Left $process1 -Right $process2 -LeftProperties Name,Sample1CPU -RightProperties Sample2CPU -Where {$args[0].Id -eq $args[1].Id} 

$samples | select Name,@{Name="CPU Usage";Expression = {($_.Sample2CPU-$_.Sample1CPU)/$sampleInterval * 100}} | sort -Property "CPU Usage" -Descending | select -First 10 | ft -AutoSize 

cual da un ejemplo de salida

Name     CPU Usage 
----     --------- 
firefox  20.8333333333333 
powershell_ise 5.72916666666667 
Battle.net    1.5625 
Skype     1.5625 
chrome     1.5625 
chrome   1.04166666666667 
chrome   1.04166666666667 
chrome   1.04166666666667 
chrome   1.04166666666667 
LCore   1.04166666666667 
+1

FYI - Join-Object no es un comando PS nativo. – KERR