我有一个Samurize配置,显示类似于任务管理器的CPU使用率图。
如何以当前最高CPU使用率百分比显示进程名称?
我希望最多每秒更新一次。 Samurize可以调用命令行工具并在屏幕上显示它的输出,所以这也可以是一个选项。
进一步澄清:
我已经研究过编写自己的命令行c#.NET应用程序来枚举从System.Diagnostics.Process.GetProcesses()返回的数组,但是Process实例类似乎没有包含CPU百分比属性。
我能以某种方式计算出来吗?
答案 0 :(得分:6)
您希望获得即时CPU使用率(种类)......
实际上,进程的即时CPU使用率不存在。相反,你必须进行两次测量并计算平均CPU使用率,公式非常简单:
AvgCpuUsed = [TotalCPUTime(process,time2) - TotalCPUTime(process,time1)] / [time2-time1]
时间2和时间1的差异越小,您的测量结果就越“即时”。 Windows任务管理器以一秒的间隔计算CPU使用率。我发现这已经足够了,您甚至可以考虑在5秒的时间间隔内完成它,因为测量本身会占用CPU周期......
首先,要获得平均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;
}
}
}
如果您希望所有进程只使用Process.GetProcesses静态方法,那么您应该从您要监控的每个进程的计时器(或您喜欢的任何间隔方法)调用该类
答案 1 :(得分:2)
以弗雷德里克的答案为基础,利用页面底部的代码here(有关用法的示例,请参阅this帖子)加入从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
答案 2 :(得分:1)
您可能可以使用Pmon.exe。您可以将其作为Windows Resource Kit tools的一部分(链接到Server 2003版本,显然也可以在XP中使用)。
答案 3 :(得分:1)
Process.TotalProcessorTime
http://msdn.microsoft.com/en-us/library/system.diagnostics.process.totalprocessortime.aspx
答案 4 :(得分:1)
不知何故
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
答案 5 :(得分:1)
感谢Jorge的公式。我不太明白为什么你必须除以核心数,但我得到的数字与任务管理器相匹配。这是我的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
答案 6 :(得分:0)
您也可以这样做: -
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);
}
答案 7 :(得分:-3)
使用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