문제

나는 사무라이즈 작업 관리자와 유사한 CPU 사용량 그래프를 보여주는 구성입니다.

현재 CPU 사용량이 가장 높은 프로세스의 이름도 표시하려면 어떻게 해야 합니까?

나는 이것이 초당 최대 한 번씩 업데이트되기를 원합니다.Samurize는 명령줄 도구를 호출하고 그 출력을 화면에 표시할 수 있으므로 이것도 옵션이 될 수 있습니다.


추가 설명:

System.Diagnostics.Process.GetProcesses()에서 반환된 배열을 열거하기 위해 자체 명령줄 C# .NET 응용 프로그램을 작성하는 방법을 조사했지만 Process 인스턴스 클래스에 CPU 비율 속성이 포함되지 않은 것 같습니다.

이것을 어떤 식으로든 계산할 수 있나요?

도움이 되었습니까?

해결책

파워셸을 사용하면:

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

다음과 같이 반환됩니다.

  16.8641632 System
   12.548072 csrss
  11.9892168 powershell

다른 팁

즉각적인 CPU 사용량을 얻고 싶은 것은 (일종의) ...

실제로 프로세스에 대한 즉각적인 CPU 사용량은 존재하지 않습니다.대신 두 가지 측정을 수행하고 평균 CPU 사용량을 계산해야 하며 공식은 매우 간단합니다.

AvgCpuUsed = [TotalCPUTime(프로세스, 시간2) - TotalCPUTime(프로세스, 시간1)] / [time2-time1]

Time2와 Time1의 차이가 낮을수록 측정이 더 "즉각적"입니다.Windows 작업 관리자는 1초 간격으로 CPU 사용량을 계산합니다.나는 그것이 충분하다는 것을 알았고 측정 작업 자체가 CPU 사이클을 차지하기 때문에 5초 간격으로 수행하는 것을 고려할 수도 있습니다.

먼저, 평균 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;
}

이제 "즉각적인" CPU 로드를 위해서는 특수 클래스가 필요합니다.

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

타이머(또는 원하는 간격 방법)에서 해당 클래스를 호출해야 합니다. 모니터링하려는 각 프로세스, 모든 프로세스를 원하면 다음을 사용하세요. 프로세스.Get프로세스 정적 방법

Frederic의 답변을 바탕으로 페이지 하단의 코드 활용 여기 (사용 예는 다음을 참조하세요. 이것 게시물)에서 얻은 전체 프로세스 세트에 참여하려면 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

당신은 사용할 수 있습니다 Pmon.exe 이를 위해.의 일부로 얻을 수 있습니다. Windows 리소스 키트 도구 (링크는 Server 2003 버전에 대한 것이며 XP에서도 사용할 수 있는 것으로 보입니다.)

어떻게든

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

원격 컴퓨터에서 CPU 정보를 가져오지 못했습니다.나는 이것을 생각해 내야했다.

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

공식 고마워요, 호르헤.왜 코어 수로 나누어야 하는지 잘 이해가 안 되지만, 작업 관리자에서 얻은 숫자는 일치합니다.내 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

이 방법으로도 할 수 있습니다 :-

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);
    }
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top