Search code examples
multiprocessingcpu-usagepidmonitorpsutil

"psutil.Process(PARENT_PID).cpu_percent(interval=0)" returns only "0.0" in multiprocessing subprocess


I have a resource demanding task and I want to monitor CPU usage of the process. I need the cpu percentage to refresh at a high and constant rate, which means that just adding print(psutil.cpu_percent(interval=0)) at various points inside the task is not a solution. I tried adding a parallel process with a timed loop, that measures the resource usage of the main process and prints it. I attempted to pass the PID of the main process to the subprocess and use it to get the usage just of the main process, but it doesn't seem to work.

This is what I came up with:

system_monitor(process_pid):
    while True:
        # Timer (waits for the right time to start the loop)
        [...]

        # Print CPU usage
        print(psutil.Process(process_pid).cpu_percent(interval=0))


main():
    process_pid = os.getpid()
    parallel_process = Process(target=system_monitor, args=(process_pid,))

    # Set as daemon so it stops when main process stops
    parallel_process.daemon = True

    parallel_process.start()

    # Resource demanding task
    [...]


if __name__ == "__main__":
    main()

The code only outputs 0.0 as if it did not remember the last call of the function and it restarted the count every time. I also tried the same code but with RAM usage (psutil.Process(process_pid).memory_info().rss) and it works great.


Solution

  • I don't know if you're still looking for the answer, but I was having the same problem and I think I figured this out. It does not work because you are re-creating the process everytime you call print(psutil.Process(process_pid).cpu_percent(interval=0)).

    Instead, you should create the process object once with p = psutil.Process(process_pid) and then you will be able to call p.cpu_percent(interval=0)) (excluding the first call that will always return 0).

    I think the reason it is working with psutil.Process(process_pid).memory_info().rss is because memory_info() does not work the same way as cpu_percent(). memory_info() gives you real time memory usage while cpu_percent(interval=0) gives you percentage since last call (unless you passed a value greater than 0 to interval).