如何得知 CPU 使用率
来源:互联网 发布:论文数据搜索 编辑:程序博客网 时间:2024/05/08 15:48
透過程式取得 CPU 使用率
<< VB.Net 使用 PerformanceCounter 的寫法 >>
Imports System.Diagnostics ' 匯入System.Diagnostics 命名空間
Public Class Form1
' 宣告並建立"效能計數器元件" 類別
' New PerformanceCounter(CategoryName,CounterName,InstanceName)
Private PfmcCounter As New PerformanceCounter("Processor", "% Processor Time", "_Total")
' CategoryName : 取得或設定這個效能計數器的效能計數器分類的名稱。
' CounterName : 取得或設定與這個PerformanceCounter 執行個體相關的效能計數器的名稱。
' InstanceName : 取得或設定這個效能計數器的執行個體名稱。
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Timer1.Interval = 900 ' Timer.Interval 屬性: 取得或設定引發Elapsed 事件的間隔。
Timer1.Enabled = True ' 啟動Timer
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
' PerformanceCounter.NextValue 方法: 取得計數器樣本,並為其傳回計算過的值。
Label1.Text = PfmcCounter.NextValue.ToString & " %"
End Sub
End Class
================================================================
<< VB.Net 使用 WMI 的寫法 >>
Dim objWMI As Object
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Timer1.Interval = 500
Timer1.Enabled = True
objWMI = GetObject("winmgmts:")
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick ' Timer 事件
CPU_Usage()
End Sub
Private Sub CPU_Usage() ' 用 WMI 取得 CPU 使用率
Dim strCls, strCPU As String
strCls = "Win32_Processor" ' WMI 類別
strCPU = "CPU0" ' 當有多顆 CPU 時 , 可調整為 CPU1 , CPU2 .. 依此類推
Debug.WriteLine(objWMI.InstancesOf(strCls)(strCls & ".DeviceID=""" & strCPU & """").LoadPercentage) ' 取得使用率
End Sub
================================================================
VB6 寫法 :
Dim objWMI As Object
Private Sub Form_Load()
Timer1.Interval = 500
Timer1.Enabled = True
Set objWMI = GetObject("winmgmts:")
End Sub
Private Sub Timer1_Timer() ' Timer 事件
CPU_Usage
End Sub
Private Sub CPU_Usage() ' 用 WMI 取得 CPU 使用率
Dim strCls As String, strCPU As String
strCls = "Win32_Processor" ' WMI 類別
strCPU = "CPU0" ' 當有多顆 CPU 時 , 可調整為 CPU1 , CPU2 .. 依此類推
Debug.Print objWMI.InstancesOf(strCls)(strCls & ".DeviceID=""" & strCPU & """").LoadPercentage ' 取得使用率
End Sub
================================================================
另外在WinNT , Win2K , WinXP , Win 2003 … 作業系統中,也可 Call API 來取得 CPU 使用率
Private Declare Function NtQuerySystemInformation Lib "ntdll" _
(ByVal dwInfoType As Long, ByVal lpStructure As Long, _
ByVal dwSize As Long, ByVal dwReserved As Long) As Long
Win98 則可透過登錄檔讀取來取取 CPU 使用率
HKEY_DYN_DATA/PerfStats/StartStat/KERNEL/CPUusage
至於您說 WMI 查詢速度 , 試了一下 , 如您所說 , 第一次取得 , 真的是慢到昏倒 , 且往後每次取得..大概在 1~ 2 秒左右
Q2 :
PerformanceCounter 的確比較快 ( 快到快飛起來囉! ) ... 使用上也 EZ ... , 非常感謝您的指教 !
弄了個簡單的 Sample , 放了個 Timer 跟 Label , Code 大致如下:
Imports System.Diagnostics
Public Class Form1
Private PfmcCounter As New PerformanceCounter("Processor", "% Processor Time", "_Total")
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Timer1.Interval = 900
Timer1.Enabled = True
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Label1.Text = PfmcCounter.NextValue.ToString & " %"
End Sub
End Class
不過感覺起來~與WINDOWS內附的工作管理員的CPU使用率~似乎不太一樣。
個人覺得是降子的
工作管理員有自己的 Timer , Interval 可能是 1 秒..(或不到 1 秒)
那我們自己寫的程式也有自己的 Timer ..
而..兩邊的 Timer Interval 一不一樣是一回事
但..起始點..一定不同囉
那 CPU 使用率..在 1 秒內..高低起伏的變化..可能值由 0 ~ 100
改變了 N 次 , 那兩邊抓到的點不同...因此值也不同
如果說...兩邊的 Timer 是同步的的.. Interval 也是一樣..
那抓出的使用率...理論上就會相同囉
後來我想把這個功能寫在網頁上,但我遇到一個問題就是,CPU的使用率永遠都是0,但Memory的資料卻是正確的但我就是找不到原因,想要請教你,Call API NtQuerySystemInformation (ntdll)可以再網頁上實作嗎?可否給我一個比較清楚的範例,或是可否告知我哪裡有相關的資料可以研讀,謝謝!!
Call API NtQuerySystemInformation (ntdll) 是 Win32 API
理論上可以 ! 不過應該會有權限跟安全性的問題
"個人是沒實作過" 在 ASP.Net 上直接呼叫 Win32 API
但應該可以將 Call API 的部份寫在 ActiveX Dll 裡
透過 DCOM 委派權限去處理執行
感覺直接使用 .Net 的類別應該會比較好
使用 整合 Windows 驗證 的方式設定 IIS 虛擬目錄的權限
您說 CPU 取到 0 , 但 Memory 都 OK !
都是 PerformanceCounter 的方式嗎 ?
理論上 Memory OK , CPU 應該也會 OK 才對
還是您方便 Po 出程式 , 在來討論看看
在下若有空 , 也會實作看看
先前提到的問題我以解決,程式碼如下所示(請參考):
Imports System.Diagnostics
Public Class WebForm2
Inherits System.Web.UI.Page
Private Shared CPU_Counter As New PerformanceCounter("Processor", "% Processor Time", "_Total")
Private Shared Mem_Counter As New PerformanceCounter("Memory", "Available MBytes")
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Label1.Text = CPU_Counter.NextValue.ToString & " %"
Label2.Text = Mem_Counter.NextValue.ToString
End Sub
End Class
先前遇到的問題是我再宣告時並未加上"shared"這個關鍵字,後來有人告訴我,加上"shared"這個關鍵字即可,我試了一下果然可以,但我並不知道為什麼會如此,若你知道原因望請不吝指點一下,謝謝!!
Shared 關鍵字相當於在 VB6 時的 Static , 也就靜態變數
PerformanceCounter("Processor", "% Processor Time", "_Total") 第一次取得 CPU 使用率會是 0
以下做個實驗:
設定中斷點在 CPU_Counter 的宣告
再來比較有加 Shared 關鍵字跟沒加的差異
個人測試的結果是 , 當沒加 Shared 關鍵字時 , 每按Button , 都會跑一次 Private CPU_Counter As ... 這行 , 有加 Shared 則不會
因此 , 當沒 Shared 時 , 每次 CPU_Counter 都重新建立 New 一個實體
而 "第一次" 取 CPU 使用率為 0 , 所以就會每次都取到 0
因此需要加 Shared 使其成為成靜態變數存在記憶體中 , 就會 OK
以上是個人觀察的結果 , 或許不是正確解答囉 .. 您參考看看!
( 怪的是 Memory 並不會有此情形 ! 或許設計原理不同的關係吧 )
原因可能是 Win Form 不會重 Load
但網頁會重新 Load ..
上述你有提到WMI 的寫法
但是讀取的速度有夠慢的
而且在讀取時會有lag的情況
有什麼另類辦法可以讀取cpu使用率呢?
上述你有提到WMI 的寫法
但是讀取的速度有夠慢的
而且在讀取時會有lag的情況
有什麼另類辦法可以讀取cpu使用率呢?
上述你有提到WMI 的寫法
但是讀取的速度有夠慢的
而且在讀取時會有lag的情況
有什麼另類辦法可以讀取cpu使用率呢?
Private Declare Function NtQuerySystemInformation Lib "ntdll" _
(ByVal dwInfoType As Long, ByVal lpStructure As Long, _
ByVal dwSize As Long, ByVal dwReserved As Long) As Long
怎麼用?
Call NtQuerySystemInformation()要怎樣使用?
誰可以提出"WINDOWS XP"可以讀取出來的方法嗎?
感謝各位大大指教
開一個 Form , 放 Timer1 , 跟 Lable1
Form 內容如下 :
Dim objQry As Object
Private Sub Form_Load()
Set objQry = New clsCPUUsage
End Sub
Private Sub Timer1_Timer()
Label1 = objQry.Query & " %"
Label1.Refresh
End Sub
新增一個物件類別模組 , Name 命為 clsCPUUsage
內容如下 :
Private Type LARGE_INTEGER
dwLow As Long
dwHigh As Long
End Type
Private Type SYSTEM_BASIC_INFORMATION
dwUnknown1 As Long
uKeMaximumIncrement As Long
uPageSize As Long
uMmNumberOfPhysicalPages As Long
uMmLowestPhysicalPage As Long
uMmHighestPhysicalPage As Long
uAllocationGranularity As Long
pLowestUserAddress As Long
pMmHighestUserAddress As Long
uKeActiveProcessors As Long
bKeNumberProcessors As Byte
bUnknown2 As Byte
wUnknown3 As Integer
End Type
Private Type SYSTEM_PERFORMANCE_INFORMATION
liIdleTime As LARGE_INTEGER
dwSpare(0 To 75) As Long
End Type
Private Type SYSTEM_TIME_INFORMATION
liKeBootTime As LARGE_INTEGER
liKeSystemTime As LARGE_INTEGER
liExpTimeZoneBias As LARGE_INTEGER
uCurrentTimeZoneId As Long
dwReserved As Long
End Type
Private Declare Function NtQuerySystemInformation Lib "ntdll" _
(ByVal dwInfoType As Long, ByVal lpStructure As Long, ByVal dwSize As Long, ByVal dwReserved As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
(pDst As Any, pSrc As Any, ByVal ByteLen As Long)
Private liOldIdleTime As LARGE_INTEGER
Private liOldSystemTime As LARGE_INTEGER
Public Sub Initialize()
Dim SysTimeInfo As SYSTEM_TIME_INFORMATION
Dim SysPerfInfo As SYSTEM_PERFORMANCE_INFORMATION
Dim Ret As Long
Ret = NtQuerySystemInformation(3&, VarPtr(SysTimeInfo), LenB(SysTimeInfo), 0&)
If Ret <> 0 Then
Debug.Print "Error while initializing the system's time!", vbCritical
Exit Sub
End If
Ret = NtQuerySystemInformation(2&, VarPtr(SysPerfInfo), LenB(SysPerfInfo), ByVal 0&)
If Ret <> 0 Then
Debug.Print "Error while initializing the CPU's idle time!", vbCritical
Exit Sub
End If
liOldIdleTime = SysPerfInfo.liIdleTime
liOldSystemTime = SysTimeInfo.liKeSystemTime
End Sub
Public Function Query() As Long
Dim SysBaseInfo As SYSTEM_BASIC_INFORMATION
Dim SysPerfInfo As SYSTEM_PERFORMANCE_INFORMATION
Dim SysTimeInfo As SYSTEM_TIME_INFORMATION
Dim dbIdleTime As Currency
Dim dbSystemTime As Currency
Dim Ret As Long
Query = -1
Ret = NtQuerySystemInformation(0&, VarPtr(SysBaseInfo), LenB(SysBaseInfo), 0&)
If Ret <> 0 Then
Debug.Print "Error while retrieving the number of processors!", vbCritical
Exit Function
End If
Ret = NtQuerySystemInformation(3&, VarPtr(SysTimeInfo), LenB(SysTimeInfo), 0&)
If Ret <> 0 Then
Debug.Print "Error while retrieving the system's time!", vbCritical
Exit Function
End If
Ret = NtQuerySystemInformation(2&, VarPtr(SysPerfInfo), LenB(SysPerfInfo), ByVal 0&)
If Ret <> 0 Then
Debug.Print "Error while retrieving the CPU's idle time!", vbCritical
Exit Function
End If
dbIdleTime = LI2Currency(SysPerfInfo.liIdleTime) - LI2Currency(liOldIdleTime)
dbSystemTime = LI2Currency(SysTimeInfo.liKeSystemTime) - LI2Currency(liOldSystemTime)
If dbSystemTime <> 0 Then dbIdleTime = dbIdleTime / dbSystemTime
dbIdleTime = 100 - dbIdleTime * 100 / SysBaseInfo.bKeNumberProcessors + 0.5
Query = Int(dbIdleTime)
liOldIdleTime = SysPerfInfo.liIdleTime
liOldSystemTime = SysTimeInfo.liKeSystemTime
End Function
Private Function LI2Currency(liInput As LARGE_INTEGER) As Currency
CopyMemory LI2Currency, liInput, LenB(liInput)
End Function
- 如何得知 CPU 使用率
- 如何获取CPU使用率
- Android 如何计算CPU使用率(CPU Usage)
- Android 如何计算CPU使用率(CPU Usage)
- 如何知道有几个CPU及其使用率?
- 如何获取CPU的主频和使用率?
- 如何解决CPU使用率过高问题
- 如何减低php程序的cpu使用率?
- cpu使用率
- CPU使用率
- CPU使用率
- CPU使用率
- CPU使用率
- CPU使用率
- CPU利用率==如何看每个CPU的使用率
- 如何解决服务器CPU使用率过高的问题<一>
- 如何解决服务器CPU使用率过高的问题<二>
- 如何定位死循环或高CPU使用率(linux) -
- 用ASP.NET对IIS中的虚拟目录进行操作
- 抽象类和接口的区别
- 票,你搞到了吗?
- 卷首语
- Windows文件系统的过滤器驱动程序设计
- 如何得知 CPU 使用率
- 北京纪行之三:探密CSDN.NET
- 1.1从Hello Qt开始
- ASP.NET 2.0服务器控件开发精要
- Google的一些秘密入口
- 挖掘 FOR 的潜力(1)
- Visual Studio2005 + Visual SourceSafe 2005 实现团队开发、源代码管理、版本控制
- 分析最新变种的"熊猫烧香"及其清除方法
- 在ASP.NET中创建安全的web站点(配置)
What People Are Saying About This Post...
我有看到"透過程式取得 CPU 使用率"這篇文章,自己實作後發現有個問題想要請教一下,望請不吝指教,謝謝!
1.我看到該篇文章有一張圖,是類似windows的工作管理員(PH CPU Viwer),有畫出CPU的使用率,但我按找你寫的CODE去實作,發現每執行一次CPU_Usage() 大約需要2秒的時間,如此依來根本很難時做出你的CPU Viewer的情況,請問你是怎麼辦到的,謝謝!!
2.據我所知.net framework裡的(System.Diagnostics.PerformanceCounter)也可以查出cpu load percentage速度似乎比較快,但參數我不會下,提供給你參考一下,謝謝!!