Sedok
Sedok

Reputation: 25

CPU Percentage Scan

I need to scan through all running processes and filter the ones with high usage. I currently have the code bellow but is taking too long to scan through them.

Is there a way that this can be done faster?


for proc in psutil.process_iter():
    try:
        cpu_usage = proc.cpu_percent(1)
        processName = proc.name()
        
        if cpu_usage > 2:
            processID = proc.pid
            print(processName , cpu_usage , processID)
    except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
        pass ```

Upvotes: 0

Views: 37

Answers (1)

Cmd858
Cmd858

Reputation: 866

The reason it is taking so long is because proc.cpu_percent(1) is a blocking function that take 1 second every time it is called. According to the docs, the function can be called once with interval None to get a starting point and then again to get an ending point. This means you could call this function on every Process object in the iterator, the wait 1 second and call the function on all of the objects again. To my understanding this should achieve the same affect with only about 1 second of delay.

Edit for clarity:

Here is an example of what I explained above. I just made it quickly so I recommend you clean it up to your use case but it does work.

import psutil, time

def getTime(proc):
    try:
        cpu_usage = proc.cpu_percent(interval=None)
        processName = proc.name()

        if cpu_usage > 2:
            processID = proc.pid
            print(processName, cpu_usage, processID)
    except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
        pass

for proc in psutil.process_iter():
    getTime(proc)

time.sleep(1)
for proc in psutil.process_iter():
    getTime(proc)

It runs the getTime function for every process initially, and as the docs state the first time the proc.cpu_percent function is called on a process with interval=None it will return 0.0 as a meaningless number because the function must get a starting point for its measurement. After this it waits 1 second and then runs getTime on every function again. This time however, it returns meaningful results because it has had 1 second per process to measure their usage. Essentially the function needs to be run twice for each but doing it like this can skip a massive amount of time compared to how you were doing it originally.

Upvotes: 1

Related Questions