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

[Linux] Process.children() hogs CPU #2350

Open
TheTechromancer opened this issue Jan 8, 2024 · 0 comments
Open

[Linux] Process.children() hogs CPU #2350

TheTechromancer opened this issue Jan 8, 2024 · 0 comments

Comments

@TheTechromancer
Copy link

Summary

  • OS: Arch Linux
  • Architecture: amd64
  • Psutil version: 5.9.5
  • Python version: 3.11.6
  • Type: performance

Description

Hi, first off thanks for making this library; it's very useful. Recently I've been running into an issue on Linux where calls to Process.children(recursive=True) take up more CPU than expected.

As you can see from the cProfile output, the call takes roughly 8 seconds of CPU time. This is strange because there are only a few subprocesses (five or less). The program is using asyncio, so there are quite a few active asyncio tasks; but these should all exist within the same thread.

It appears the real culprit here is _pslinux.py / ppid_map():

   Ordered by: cumulative time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000   16.932   16.932 scanner.py:557(stop)
        2    0.000    0.000   16.837    8.418 misc.py:1071(kill_children)
        4    0.000    0.000   16.826    4.207 __init__.py:270(wrapper)
        2    0.000    0.000   16.800    8.400 __init__.py:881(children)
        2    0.011    0.006   16.769    8.385 _pslinux.py:1624(ppid_map)

Here is the python code that calls it:

def kill_children(parent_pid=None, sig=signal.SIGTERM):
    """
    Forgive me father for I have sinned
    """
    try:
        parent = psutil.Process(parent_pid)
    except psutil.NoSuchProcess:
        log.debug(f"No such PID: {parent_pid}")
    log.debug(f"Killing children of process ID {parent.pid}")
    children = parent.children(recursive=True) # <---------
    for child in children:
        log.debug(f"Killing child with PID {child.pid}")
        if child.name != "python":
            try:
                child.send_signal(sig)
            except psutil.NoSuchProcess:
                log.debug(f"No such PID: {child.pid}")
            except psutil.AccessDenied:
                log.debug(f"Error killing PID: {child.pid} - access denied")
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

1 participant