我使用.NET的System.Management
東西來監視一些使用WMI的計算機。我使用的查詢是這樣的:過去的WMI,負CPU使用率值和Timestamp_Sys100NS
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
簡單地添加到時間郵票(current
)返回由WMI在Timestamp_Sys100NS
場...
if (time.Year < 2000)
time = boot_time + current;
EDIT 4: 似乎有3類系統相對於Timestamp_Sys100NS
:
- 首先是Vista的+系統,其中
Timestamp_Sys100NS
是時間,因爲在UTC紀元蜱。 - 其次是一些Windows 2003系統,需要將
Timestamp_Sys100NS
添加到Win32_OperatingSystem.LastBootUpTime
才能獲得合理的時間。 - 第三類是系統,上述添加仍然會導致日期和日期偏離正確的日期和時間。
編輯5:部分受影響的機器可能是虛擬機,但不是全部虛擬機。
這意味着CPU正在使用你:) –
你是如何將LastBootUpTime添加到TimeStamp_Sys100NS的?你做了什麼樣的轉換? – raz3r
@ raz3r:我使用'System.DateTime(Int64)'ctor(需要滴答),並將其添加到LastBootUpTime。我將只能明天查看確切的細節。 – wilx