如何得知 CPU 使用率

 

透過程式取得 CPU 使用率

 

PH Info Pic 1

 

 

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

 

 
 
posted on Wednesday, June 21, 2006 1:25 PM
href="http://blog.blueshop.com.tw/hammerchou/Services/Pingback.aspx" rel="pingback" />

What People Are Saying About This Post...

Dear sir:
我有看到"透過程式取得 CPU 使用率"這篇文章,自己實作後發現有個問題想要請教一下,望請不吝指教,謝謝!
1.我看到該篇文章有一張圖,是類似windows的工作管理員(PH CPU Viwer),有畫出CPU的使用率,但我按找你寫的CODE去實作,發現每執行一次CPU_Usage() 大約需要2秒的時間,如此依來根本很難時做出你的CPU Viewer的情況,請問你是怎麼辦到的,謝謝!!

2.據我所知.net framework裡的(System.Diagnostics.PerformanceCounter)也可以查出cpu load percentage速度似乎比較快,但參數我不會下,提供給你參考一下,謝謝!!



#  re: 如何得知 CPU 使用率 10/10/2006 8:52 PM Power Hammer
Q1 : 不好意思 , 是這樣的 , PH CPU / Memory Viewer , CPU Usage 的部份 , 是 Call API NtQuerySystemInformation (ntdll) , 所以比較快囉 !
至於您說 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


#  re: 如何得知 CPU 使用率 10/11/2006 11:54 AM scott
感謝你的回應~~試了一下~~果然是可以WORK~~謝謝!!
不過感覺起來~與WINDOWS內附的工作管理員的CPU使用率~似乎不太一樣。

#  re: 如何得知 CPU 使用率 10/11/2006 2:24 PM Power Hammer
您是不是感覺抓出的CPU使用率跟TaskMgr不一樣
個人覺得是降子的

工作管理員有自己的 Timer , Interval 可能是 1 秒..(或不到 1 秒)
那我們自己寫的程式也有自己的 Timer ..

而..兩邊的 Timer Interval 一不一樣是一回事
但..起始點..一定不同囉

那 CPU 使用率..在 1 秒內..高低起伏的變化..可能值由 0 ~ 100
改變了 N 次 , 那兩邊抓到的點不同...因此值也不同

如果說...兩邊的 Timer 是同步的的.. Interval 也是一樣..
那抓出的使用率...理論上就會相同囉


#  re: 如何得知 CPU 使用率 10/11/2006 3:29 PM scott
嗯~你說的沒錯~感謝你的指教~
後來我想把這個功能寫在網頁上,但我遇到一個問題就是,CPU的使用率永遠都是0,但Memory的資料卻是正確的但我就是找不到原因,想要請教你,Call API NtQuerySystemInformation (ntdll)可以再網頁上實作嗎?可否給我一個比較清楚的範例,或是可否告知我哪裡有相關的資料可以研讀,謝謝!!

#  re: 如何得知 CPU 使用率 10/12/2006 3:42 PM Power Hammer
您好

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 出程式 , 在來討論看看

在下若有空 , 也會實作看看


#  re: 如何得知 CPU 使用率 10/12/2006 4:44 PM scott
你好:
先前提到的問題我以解決,程式碼如下所示(請參考):

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"這個關鍵字即可,我試了一下果然可以,但我並不知道為什麼會如此,若你知道原因望請不吝指點一下,謝謝!!

#  re: 如何得知 CPU 使用率 10/17/2006 5:05 PM Power Hammer
您好

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 並不會有此情形 ! 或許設計原理不同的關係吧 )



#  re: 如何得知 CPU 使用率 10/17/2006 5:09 PM Power Hammer
對了 , Win Form 並不會有此問題
原因可能是 Win Form 不會重 Load
但網頁會重新 Load ..

#  re: 如何得知 CPU 使用率 10/18/2006 9:06 AM scott
謝謝!!

#  re: 如何得知 CPU 使用率 12/10/2006 2:42 PM 窃听器
good~

#  re: 如何得知 CPU 使用率 12/12/2006 9:29 PM lala
請問要怎樣用vb6寫出讀取cpu使用率的程式呢?
上述你有提到WMI 的寫法
但是讀取的速度有夠慢的
而且在讀取時會有lag的情況

有什麼另類辦法可以讀取cpu使用率呢?

#  re: 如何得知 CPU 使用率 12/12/2006 9:29 PM lala
請問要怎樣用vb6寫出讀取cpu使用率的程式呢?
上述你有提到WMI 的寫法
但是讀取的速度有夠慢的
而且在讀取時會有lag的情況

有什麼另類辦法可以讀取cpu使用率呢?

#  re: 如何得知 CPU 使用率 12/12/2006 9:29 PM lala
請問要怎樣用vb6寫出讀取cpu使用率的程式呢?
上述你有提到WMI 的寫法
但是讀取的速度有夠慢的
而且在讀取時會有lag的情況

有什麼另類辦法可以讀取cpu使用率呢?

#  re: 如何得知 CPU 使用率 12/12/2006 9:32 PM lala
還有
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"可以讀取出來的方法嗎?
感謝各位大大指教

#  re: 如何得知 CPU 使用率 12/14/2006 11:05 AM 硬盘数据恢复
不错~

#  re: 如何得知 CPU 使用率 12/26/2006 3:17 PM Power Hammer
Sample , 參考看看
開一個 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 
 
#  re: 如何得知 CPU 使用率 10/5/2006 2:12 PM scott
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值