I need to get CPU % for each process thread.
So, I create simple script:
import psutil
from psutil import Process
p = psutil.Process(4499)
treads_list = p.get_threads()
for i in treads_list:
o = i[0]
th = psutil.Process(o)
cpu_perc = th.get_cpu_percent(interval=1)
print('PID %s use %% CPU = %s' % (o, cpu_perc))
Here is how TOP looks like for this process:
4942 teamcity 20 0 3288m 831m 3124 R 33.3 10.6 10303:37 java
32700 teamcity 20 0 3288m 831m 3124 S 5.9 10.6 18:49.99 java
5824 teamcity 20 0 3288m 831m 3124 S 5.9 10.6 1:57.90 java
4621 teamcity 20 0 3288m 831m 3124 S 3.0 10.6 1834:09 java
4622 teamcity 20 0 3288m 831m 3124 S 2.6 10.6 1844:15 java
Threads use 2.6-5.9 % CPU, and parent PID - use 33.3.
But - here is script's result:
# ./psutil_threads.py
PID 10231 use % CPU = 60.9
PID 10681 use % CPU = 75.3
PID 11371 use % CPU = 69.9
PID 11860 use % CPU = 85.9
PID 12977 use % CPU = 56.0
PID 14114 use % CPU = 88.8
Looks like each thread 'eat' 56-88 % CPU...
What I'm missing here?
A thread is inactive when in the blocked or waiting state. When in these states, the thread does not consume any CPU cycles. A thread is in the waiting state when it wants to wait on a signal from another thread before proceeding. Once this signal is received, it becomes runnable.
The best solution to limiting the cpu usage for a process or thread is to make sure that the thread or process uses less cpu. That can best be done by improving the efficiency of the code, or by calling it less often. The aim is to make sure that the process doesn't continually consume all of its available time slice.
This should give you what you need and match top (adapt to your use case):
import psutil
def get_threads_cpu_percent(p, interval=0.1):
total_percent = p.get_cpu_percent(interval)
total_time = sum(p.cpu_times())
return [total_percent * ((t.system_time + t.user_time)/total_time) for t in p.get_threads()]
# Example usage for process with process id 8008:
proc = psutil.Process(8008)
print(get_threads_cpu_percent(proc))
get_cpu_percent(interval=0.1)
Return a float representing the process CPU utilization as a percentage.
When interval is > 0.0 compares process times to system CPU times elapsed before and after the interval (blocking).
When interval is 0.0 or None compares process times to system CPU times elapsed since last call, returning immediately. In this case is recommended for accuracy that this function be called with at least 0.1 seconds between calls.
This sounds a lot like it will give you how much of the CPU time spent non-idle is returned (that is: amount of process CPU time per system CPU time), while top shows the amount of CPU time of the process in relation to real time. This seems realistic given your numbers.
To get the values top would show you, simply multiplying each threads' CPU usage by the CPU usage of the core the thread runs on should work. psutil.cpu_percent
should help with that. Note that you need to divide percentages by 100.0 (to get a "percentage" between 0 and 1) before multiplying them.
While Gabe's answer is great, note that newer psutil version requires the following updated syntax:
import psutil
def get_threads_cpu_percent(p, interval=0.1):
total_percent = p.cpu_percent(interval)
total_time = sum(p.cpu_times())
return [total_percent * ((t.system_time + t.user_time)/total_time) for t in p.threads()]
# Example usage for process with process id 8008:
proc = psutil.Process(8008)
print(get_threads_cpu_percent(proc))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With