Название процесса с наибольшим использованием процессора - PullRequest
5 голосов
/ 09 сентября 2008

У меня есть конфигурация Samurize , которая показывает график использования ЦП, аналогичный диспетчеру задач.

Как мне также отобразить имя процесса с текущим самым высоким процентом использования ЦП?

Я бы хотел, чтобы это обновлялось максимум раз в секунду. Samurize может вызвать инструмент командной строки и отобразить его вывод на экран, так что это также может быть вариантом.


Дополнительные уточнения:

Я исследовал написание собственного приложения для командной строки c # .NET для перечисления массива, возвращенного из System.Diagnostics.Process.GetProcesses (), но класс экземпляра Process, по-видимому, не включает процентное свойство CPU.

Можно ли как-нибудь рассчитать это?

Ответы [ 8 ]

6 голосов
/ 09 сентября 2008

То, что вы хотите получить, это мгновенное использование процессора (вид) ...

На самом деле, мгновенное использование процессора для процесса не существует. Вместо этого вам нужно сделать два измерения и рассчитать среднее использование процессора, формула довольно проста:

AvgCpuUsed = [TotalCPUTime (процесс, время2) - TotalCPUTime (процесс, время1)] / [время2-время1]

Чем меньше разница в Time2 и Time1, тем более «мгновенным» будет ваше измерение. Диспетчер задач Windows рассчитывает загрузку процессора с интервалом в одну секунду. Я обнаружил, что этого более чем достаточно, и вы можете даже подумать о том, чтобы делать это с интервалами в 5 секунд, поскольку сам процесс измерения занимает циклы ЦП ...

Итак, во-первых, чтобы получить среднее время процессора

    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;
}

теперь, для «мгновенной» загрузки процессора вам понадобится специализированный класс:

 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;
    }
  }
}

Вы должны вызывать этот класс из таймера (или любого другого метода интервала, который вам нравится) для каждого процесса, который вы хотите отслеживать , если вы хотите, чтобы все процессы просто использовали Process.GetProcesses статический метод

2 голосов
/ 11 июля 2015

Опираясь на ответ Фредерика и используя код внизу страницы здесь (пример использования см. this post), чтобы присоединиться к полному набору процессов, полученных из Get-Process, получаем следующее:

$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

Что дает пример вывода

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 голос
/ 27 марта 2014

Спасибо за формулу, Хорхе. Я не совсем понимаю, почему вы должны делить на количество ядер, но числа, которые я получаю, соответствуют диспетчеру задач. Вот мой код 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
1 голос
/ 20 октября 2013

Как-то

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

не получает информацию о процессоре с удаленного компьютера. Я должен был придумать это.

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 голос
/ 09 сентября 2008
1 голос
/ 09 сентября 2008

Для этого вы можете использовать Pmon.exe . Вы можете получить его как часть Инструментов Windows Resource Kit (ссылка на версию Server 2003, которая также может использоваться в XP).

0 голосов
/ 17 марта 2013

Вы также можете сделать это следующим образом: -

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];
    }

Использование: -

static void Main()
    {
        Process mxp=getProcessWithMaxCPUUsage();
        Console.WriteLine(mxp.ProcessName);
    }
0 голосов
/ 09 сентября 2008

С PowerShell:

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

возвращает что-то вроде:

  16.8641632 System
   12.548072 csrss
  11.9892168 powershell
...