Nom du processus avec l'utilisation la plus élevée du processeur
-
09-06-2019 - |
Question
j'ai un Samouriser config qui montre un graphique d'utilisation du processeur similaire au Gestionnaire de tâches.
Comment puis-je également afficher le nom du processus avec le pourcentage d'utilisation du processeur actuel le plus élevé ?
J'aimerais que cela soit mis à jour au maximum une fois par seconde.Samurize peut appeler un outil de ligne de commande et afficher sa sortie à l'écran, cela pourrait donc également être une option.
Plus de précisions:
J'ai étudié l'écriture de ma propre application c# .NET en ligne de commande pour énumérer le tableau renvoyé par System.Diagnostics.Process.GetProcesses(), mais la classe d'instance Process ne semble pas inclure de propriété de pourcentage de CPU.
Puis-je calculer cela d'une manière ou d'une autre ?
La solution
Avec PowerShell :
Get-Process | Sort-Object CPU -desc | Select-Object -first 3 | Format-Table CPU,ProcessName -hidetableheader
renvoie un peu comme :
16.8641632 System
12.548072 csrss
11.9892168 powershell
Autres conseils
Ce que vous voulez obtenir, c'est l'utilisation instantanée du processeur (en quelque sorte)...
En fait, l'utilisation instantanée du processeur pour un processus n'existe pas.Au lieu de cela, vous devez effectuer deux mesures et calculer l’utilisation moyenne du processeur, la formule est assez simple :
AvgCpuUsed = [TotalCPUTime(process,time2) - TotalCPUTime(process,time1)] / [time2-time1]
Plus la différence entre Time2 et Time1 est faible, plus votre mesure sera « instantanée ».Le Gestionnaire des tâches de Windows calcule l'utilisation du processeur avec un intervalle d'une seconde.J'ai trouvé que c'est plus que suffisant et vous pourriez même envisager de le faire à intervalles de 5 secondes, car le fait de se mesurer prend des cycles CPU...
Donc, d’abord, pour obtenir le temps CPU moyen
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;
}
maintenant, pour la charge CPU "instantanée", vous aurez besoin d'une classe spécialisée :
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;
}
}
}
Vous devez appeler cette classe à partir d'un minuteur (ou de la méthode d'intervalle de votre choix) pour chaque processus que vous souhaitez surveiller, si vous voulez tous les processus, utilisez simplement le Processus.GetProcesses méthode statique
S'appuyer sur la réponse de Frédéric et utiliser le code en bas de page ici (pour un exemple d'utilisation, voir ce post) pour rejoindre l'ensemble complet des processus obtenus à partir de Get-Process
, on obtient ce qui suit :
$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
Ce qui donne un exemple de sortie de
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
Vous pourrez peut-être utiliser Pmon.exe pour ça.Vous pouvez l'obtenir dans le cadre du Outils du Kit de ressources Windows (le lien est vers la version Server 2003, qui peut apparemment également être utilisée sous XP).
Process.TotalProcessorTime
http://msdn.microsoft.com/en-us/library/system.diagnostics.process.totalprocessortime.aspx
D'une manière ou d'une autre
Get-Process | Sort-Object CPU -desc | Select-Object -first 3 | Format-Table CPU,ProcessName,TotalProcessorTime -hidetableheader
je n'obtenais pas les informations sur le processeur de la machine distante.Je devais trouver ça.
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
Merci pour la formule, Jorge.Je ne comprends pas très bien pourquoi vous devez diviser par le nombre de cœurs, mais les chiffres que j'obtiens correspondent au Gestionnaire des tâches.Voici mon code 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
Vous pouvez également procéder de cette façon :-
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];
}
Usage:-
static void Main()
{
Process mxp=getProcessWithMaxCPUUsage();
Console.WriteLine(mxp.ProcessName);
}