【发布时间】:2012-01-06 06:25:11
【问题描述】:
我正在使用 .NET 的 System.Management 东西监视一些使用 WMI 的机器。我正在使用的查询是这样的:
SELECT Timestamp_Sys100NS, PercentProcessorTime
FROM Win32_PerfRawData_PerfOS_Processor
WHERE Name='_Total'
据此,我使用众所周知的公式计算 CPU 使用率:
double cpu_usage = (1 - (double)delta_cpu / delta_time) * 100;
除了一台(到目前为止)之外,每台机器都运行良好。
问题在于,对于一台机器,即 Windows 2003 服务器(启用超线程,如果重要的话),我有时会得到负 CPU 使用率值。换句话说,(double)delta_cpu / delta_time 表达式产生数字> 1。我确实在网上搜索了有关为什么会发生这种情况的提示,但我一无所获。
这是 Windows 2003 服务器特定的吗?还是与超线程相关的问题?还是只是预期的,我应该将 CPU 使用率值或 cpu_delta 值限制在某个范围内?
编辑:
我在这台机器上观察到的第二个奇怪的事情是,Timestamp_Sys100NS 值并不表示 FILETIME 喜欢日期(自 1600 年 1 月 1 日以来的滴答声),而是从启动时间开始的滴答声。
编辑 2: 我现在已经证实这个问题存在于许多 Windows 2003 服务器上。我显然是not the only one with the same problem。
编辑 3:
我通过从Win32_OperatingSystem 查询LastBootUpTime 并在Timestamp_Sys100NS 的值过去太远时将其添加到Timestamp_Sys100NS 解决了时间戳问题。这似乎给出了正确的日期和时间。从Win32_OperatingSystem 检索到日期后操作日期的代码如下所示:
WbemScripting.SWbemDateTime swbem_time = new WbemScripting.SWbemDateTime();
swbem_time.Value = date_str;
string time_as_file_time_str = swbem_time.GetFileTime(true);
return new DateTimeOffset(epoch.Ticks + long.Parse(time_as_file_time_str),
swbem_time.UTCSpecified
? TimeSpan.FromMinutes(swbem_time.UTC)
: TimeSpan.Zero);
...然后调整到 UTC...
boot_time = boot_time.UtcDateTime;
...然后是 boot_time 简单地添加到由 WMI 在 Timestamp_Sys100NS 字段中返回的时间戳 (current)...
if (time.Year < 2000)
time = boot_time + current;
编辑 4:
关于Timestamp_Sys100NS,似乎有3类系统:
- 首先是 Vista+ 系统,其中
Timestamp_Sys100NS是UTC 纪元以来的时间。 - 其次是一些 Windows 2003 系统,需要将
Timestamp_Sys100NS添加到Win32_OperatingSystem.LastBootUpTime以获得合理的时间。 - 第三类是执行上述添加仍会导致日期和时间偏离正确日期和时间的系统。
编辑 5:一些受影响的机器可能是虚拟机,但不是全部。
【问题讨论】:
-
这意味着CPU正在使用你:)
-
如何将 LastBootUpTime 添加到 TimeStamp_Sys100NS?你做了什么样的转换?
-
@raz3r:我正在使用
System.DateTime(Int64)ctor(需要滴答声)并将其添加到 LastBootUpTime。明天我才能检查确切的细节。