Search code examples
pythonwindowspywin32

Calculating process cpu usage by Python


I'm trying to get (by a pid) the process cpu usage. I did some research about it and I found out that I can calculate it by using the GetSystemTimes() function. I found the calculation in this link: http://www.codeproject.com/Articles/10258/How-to-get-CPU-usage-of-processes-and-threads

And I need this code in Python But I don't know how to do this. So I found this code: https://sites.google.com/site/cadspython/home/modules/calcprocesscpuusage-py

I was trying to run it, and everything was working fine, but when I ran a little Python program (which took 28% from the cpu utilization), the code was showing me 100% and 98%. Which is not good.

So, I am asking for a code which calculate a process cpu usage by using the GetSystemTimes() function in Python (with pywin32).

Thanks in advance.


Solution

  • After a little more research I found the solution.

    So in order to get the % of a process cpu usage we need some parameters:

    1. System time

    To calculate this we need user mode time, kernel mode time and idle mode time:

        from ctypes import *
        import time
    
        class FILETIME(Structure):
           _fields_ = [
              ("dwLowDateTime", DWORD),
              ("dwHighDateTime", DWORD)]
    
        def GetSystemTimes():
            """
            Uses the function GetSystemTimes() (win32) in order to get the user    mode time, kernel mode time and idle mode time
            :return: user time, kernel time and idle time (Dictinary)
            """
    
            __GetSystemTimes = windll.kernel32.GetSystemTimes
            idleTime, kernelTime, userTime = FILETIME(), FILETIME(), FILETIME()
    
            success = __GetSystemTimes(
    
            byref(idleTime),
            byref(kernelTime),
            byref(userTime))
    
            assert success, ctypes.WinError(ctypes.GetLastError())[1]
    
            return {
                "idleTime": idleTime.dwLowDateTime,
                "kernelTime": kernelTime.dwLowDateTime,
                "userTime": userTime.dwLowDateTime
               }
    
    
        def get_sys():  
    
            FirstSystemTimes = GetSystemTimes()
            time.sleep(SLEEP_TIME_1_5)
            SecSystemTimes = GetSystemTimes()
    
            """
             The total amount of time the system has operated since the last measurement is calculated by getting 
             kernel + user
            """
    
           usr = SecSystemTimes['userTime'] - FirstSystemTimes['userTime']
           ker = SecSystemTimes['kernelTime'] - FirstSystemTimes['kernelTime']
           idl = SecSystemTimes['idleTime'] - FirstSystemTimes['idleTime']
    
           sys = usr + ker
           return sys
    

    2. Process user mode time and process kernel time

    To get these parameters first we need to create a new process handle and then we will be able to get the process user mode time and process kernel time:

    def cpu_process_util(pid):
        """
        Returns the process usage of CPU
    
        Source: http://www.philosophicalgeek.com/2009/01/03/determine-cpu-usage-of-current-process-c-and-c/
        :return: Process CPU usage (int)
        """
    
        # Creates a process handle
        proc = win32api.OpenProcess(ALL_PROCESS_ACCESS, False, pid)
    
        FirstProcessTimes = win32process.GetProcessTimes(proc)
        time.sleep(SLEEP_TIME_1_5)
        SecProcessTimes = win32process.GetProcessTimes(proc)
    
        """
         Process CPU usage is calculated by getting the total amount of time
         the system has operated since the last measurement
         made up of kernel + user) and the total
         amount of time the process has run (kernel + user).
        """
    
        proc_time_user_prev = FirstProcessTimes['UserTime']
        proc_time_kernel_prev = FirstProcessTimes['KernelTime']
    
        proc_time_user = SecProcessTimes['UserTime']
        proc_time_kernel = SecProcessTimes['KernelTime']
    
        proc_usr = proc_time_user - proc_time_user_prev
        proc_ker = proc_time_kernel - proc_time_kernel_prev
    
        proc_total_time = proc_usr + proc_ker
    
        return (100 * proc_total_time) / get_sys()