Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Ubuntu] Child process cpu_percent() returns 0 #2351

Closed
dorinclisu opened this issue Jan 16, 2024 · 3 comments
Closed

[Ubuntu] Child process cpu_percent() returns 0 #2351

dorinclisu opened this issue Jan 16, 2024 · 3 comments

Comments

@dorinclisu
Copy link

Summary

  • OS: Ubuntu
  • Architecture: 64bit
  • Psutil version: 5.9.7
  • Python version: 3.10.12
  • Type: core

Description

Replicable code:

import subprocess
import time

import psutil  # type: ignore


process = psutil.Process()
interval = 5


# Main process test
process.cpu_percent(interval=None)
print(f'Main {process} {process.cpu_times()}')

t = time.time()
while time.time() - t < interval:
    pass

cpu_usage = process.cpu_percent(interval=None)
print(f'Main {process} {process.cpu_times()}')
print(f'Main CPU (%): {cpu_usage} (expecting ~100)')


# Child process test
cmd = f'''
keep_cpu_busy() {{
    end=$((SECONDS+{interval}))
    while [ $SECONDS -lt $end ]; do
        :
    done
}}
keep_cpu_busy
'''
p = subprocess.Popen(['bash', '-c', cmd])

for child in process.children(recursive=True):
    child.cpu_percent(interval=None)
    print(f'Child {child} {child.cpu_times()}')

cpu_usage = 0
time.sleep(interval - 1)

for child in process.children(recursive=True):
    cpu_usage += child.cpu_percent(interval=None)
    print(f'Child {child} {child.cpu_times()}')

print(f'Child CPU (%): {cpu_usage} (expecting ~100)')
p.wait()

Basically, cpu_usage works as expected for the main process, but not for the child spawned with subprocess.Popen, expecting ~100 but getting 0.0 instead.

@giampaolo
Copy link
Owner

giampaolo commented Jan 17, 2024

This part:

for child in process.children(recursive=True):
    cpu_usage += child.cpu_percent(interval=None)

...creates a set of brand new Process instances, upon which you immediately call cpu_percent(). They have no knowledge of what happened before, nor they have a big enough time window to calculate a meaningful percent value, hence they return 0.
From the doc:

the first time this cpu_percent() is called with interval = 0.0 or None it will return a meaningless 0.0 value which you are supposed to ignore

@dorinclisu
Copy link
Author

I was assuming there is a state stored outside the psutil.Process instance, since the pcputimes.user value is consistent with the actual child that exists before its psutil twin instantiation.
And I could argue the documentation is confusing, because child.cpu_percent() is being called a first time (so as to ignore its meaningless 0.0 value), according to the PID, but not according to the psutil instance.

@giampaolo
Copy link
Owner

And I could argue the documentation is confusing, because child.cpu_percent() is being called a first time (so as to ignore its meaningless 0.0 value), according to the PID, but not according to the psutil instance.

I read it twice but I don't understand what you mean here. If you have suggestions on how to reword the doc please go for it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants