如何得知 CPU 使用率

    技术2022-05-11  95

    如何得知 CPU 使用率

     

    透過程式取得 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  

     

     
      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

    最新回复(0)