pythoncpucpu-usagepsutil

How to monitor usage of CPU when function is called in Python psutil?


Hey I'm learning psutil package and I want to know how to display current CPU usage when function is in progress? I suppose I need some threading or something like this, but how to do it? Thank u for any answers.

import psutil
import random

def iHateThis():
    tab = []
    for i in range(100000):
        tab.append(random.randint(1, 10000))

    tab.sort()
    return tab;

while(True):
    currentProcess = psutil.Process()
    print(currentProcess.cpu_percent(interval=1))

Solution

  • You can use threading to run iHateThis or to run function with cpu_percent(). I choose second version. I will run cpu_percent() in thread.

    Because it uses while True so thread would run forever and there wouldn't be nice method to stop thread so I use global variaable running with while running to have method to stop this loop.

    import threading
    import psutil
    
    def display_cpu():
        global running
    
        running = True
    
        currentProcess = psutil.Process()
    
        # start loop
        while running:
            print(currentProcess.cpu_percent(interval=1))
    
    def start():
        global t
    
        # create thread and start it
        t = threading.Thread(target=display_cpu)
        t.start()
        
    def stop():
        global running
        global t
    
        # use `running` to stop loop in thread so thread will end
        running = False
    
        # wait for thread's end
        t.join()
        
    

    and now I can use it to start and stop thread which will display CPU. Because I may have to stop process using Ctrl+C so it will raise error so I use try/finally to stop thread even if there will be error.

    def i_hate_this():
        tab = []
        for i in range(1000000):
            tab.append(random.randint(1, 10000))
        tab.sort()
        return tab
    
    # ---
    
    start()
    try:
        result = i_hate_this()
    finally: # stop thread even if I press Ctrl+C
        stop()
    

    Full code:

    import random
    import threading
    import psutil
        
    def display_cpu():
        global running
    
        running = True
    
        currentProcess = psutil.Process()
    
        # start loop
        while running:
            print(currentProcess.cpu_percent(interval=1))
    
    def start():
        global t
    
        # create thread and start it
        t = threading.Thread(target=display_cpu)
        t.start()
        
    def stop():
        global running
        global t
    
        # use `running` to stop loop in thread so thread will end
        running = False
    
        # wait for thread's end
        t.join()
    
    # ---
    
    def i_hate_this():
        tab = []
        for i in range(1000000):
            tab.append(random.randint(1, 10000))
        tab.sort()
        return tab
    
    # ---
    
    start()
    try:
        result = i_hate_this()
    finally: # stop thread even if I press Ctrl+C
        stop()
    

    BTW: this can be converted to class which inherits from class Thread and then it can hide variable running in class.

    import psutil
    import random
    import threading
    
    class DisplayCPU(threading.Thread):
    
        def run(self):
    
            self.running = True
    
            currentProcess = psutil.Process()
    
            while self.running:
                print(currentProcess.cpu_percent(interval=1))
    
        def stop(self):
            self.running = False
        
    # ---
    
    def i_hate_this():
        tab = []
        for i in range(1000000):
            tab.append(random.randint(1, 10000))
        tab.sort()
        return tab
    
    # ---
    
    display_cpu = DisplayCPU()
    
    display_cpu.start()
    try:
        result = i_hate_this()
    finally: # stop thread even when I press Ctrl+C
        display_cpu.stop()
    

    It could be also converted to context manager to run it as

    import psutil
    import random
    import threading
    
    class DisplayCPU(threading.Thread):
    
        def run(self):
            self.running = True
            currentProcess = psutil.Process()
            while self.running:
                print(currentProcess.cpu_percent(interval=1))      
    
        def stop(self):
            self.running = False
        
        def __enter__(self):
            self.start()
    
        def __exit__(self, exc_type, exc_value, exc_traceback):
            self.stop()
    
    # ----
    
    display_cpu = DisplayCPU()
    
    with display_cpu():
        i_hate_this()
    

    but I skip this part.