简体   繁体   中英

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

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

with display_cpu():
    i_hate_this()

but I skip this part.

You can do this with the multiprocessing library. multiprocessing.Process is a class that represents a threaded process, is initiated with a function and name, and can be run at any time with .start() .

import multiprocessing
import psutil
import random

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

hate = multiprocessing.Process(name='hate', target=iHateThis)
hate.start()

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

I don't think you need to use psutil Process class as I think it is intended to be used to monitor a specific process. Using the code snippet from @furas (the accepted answer), you can do it with a thread like this:

def run(self):
    self.run = True 
    while self.run:
        psutil.cpu_percent(interval=1)

it works the same as the accepted answer in the following case:

    _monitor.start()
    try:
        for i in range(50):
            time.sleep(0.2)
    finally:    
        _monitor.stop()

If you don't want to code it, I am doing it in a public repo if it can be of any help for someone: https://github.com/GTimothee/monitor

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM