# Finding CPU% of a linux task

**URL:** <https://www.ruby-forum.com/t/finding-cpu-of-a-linux-task/60829>\
**Category:** Ruby\
**Created:** [January 10, 2006, 10:32pm UTC](https://www.ruby-forum.com/t/finding-cpu-of-a-linux-task/60829 "2006-01-10T22:32:35Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![joe-dumoulin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9dc877/32.png) [@joe-dumoulin](https://www.ruby-forum.com/u/joe-dumoulin)\
**Post date:** [January 10, 2006, 10:32pm UTC](https://www.ruby-forum.com/t/finding-cpu-of-a-linux-task/60829/1 "2006-01-10T22:32:35Z")

</div>

Hi,

I’m writing a small Ruby module that can find how much cpu percentage  
a given task is using. I’m doing it by getting the process id of the  
task that I care about, going into proc, checking the stat file for  
the process (which contains how many jiffies the task has consumed)  
and averaging the change of that over time to get a running  
percentage.

However, that doesn’t capture threads or forked processes. If a  
program starts a couple threads (or forks a child process), I then  
have to figure out the cpu percentage of each of the child threads  
(and their childs and their child’s childs, and so on) and add them  
together to get a total for the process.

I’m struggling to come up with an elegant way to solve this problem.  
Any ideas?

Thanks,  
Joe

---

<div class="post-metadata">

**Author:** ![joe-dumoulin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9dc877/32.png) [@joe-dumoulin](https://www.ruby-forum.com/u/joe-dumoulin)\
**Post date:** [January 10, 2006, 10:35pm UTC](https://www.ruby-forum.com/t/finding-cpu-of-a-linux-task/60829/2 "2006-01-10T22:35:37Z")

</div>

On Jan 10, 2006, at 3:31 PM, Joe Van D. wrote:

> However, that doesn’t capture threads or forked processes. If a  
> program starts a couple threads (or forks a child process), I then  
> have to figure out the cpu percentage of each of the child threads  
> (and their childs and their child’s childs, and so on) and add them  
> together to get a total for the process.

Ruby’s threads are in process, so they should already be in your  
percentage, shouldn’t they?

James Edward G. II

---

<div class="post-metadata">

**Author:** ![joe-dumoulin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9dc877/32.png) [@joe-dumoulin](https://www.ruby-forum.com/u/joe-dumoulin)\
**Post date:** [January 10, 2006, 10:44pm UTC](https://www.ruby-forum.com/t/finding-cpu-of-a-linux-task/60829/3 "2006-01-10T22:44:41Z")

</div>

On 1/10/06, James Edward G. II [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> On Jan 10, 2006, at 3:31 PM, Joe Van D. wrote:
> 
> > However, that doesn’t capture threads or forked processes. If a  
> > program starts a couple threads (or forks a child process), I then  
> > have to figure out the cpu percentage of each of the child threads  
> > (and their childs and their child’s childs, and so on) and add them  
> > together to get a total for the process.
> 
> Ruby’s threads are in process, so they should already be in your  
> percentage, shouldn’t they?

To clarify, these aren’t Ruby processes I’m tracking.

Sample usage of my class:

pi = ProcessInfo.new   
pi.cpu\_percentage # returns the cpu % of the process  
pi.running? # sees if the process is still running

etc

I added ProcessInfo#child\_tasks, that searches /proc for all child  
tasks of the process. But then, when I calculate the cpu% of the  
process, I need to recursively go in and get all the cpu% of all the  
child threads/processes of the process. And my code got ugly fast.

---

<div class="post-metadata">

**Author:** ![joe-dumoulin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9dc877/32.png) [@joe-dumoulin](https://www.ruby-forum.com/u/joe-dumoulin)\
**Post date:** [January 10, 2006, 11:08pm UTC](https://www.ruby-forum.com/t/finding-cpu-of-a-linux-task/60829/4 "2006-01-10T23:08:00Z")

</div>

On 1/10/06, Joe Van D. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > percentage, shouldn’t they?
> 
> I added ProcessInfo#child\_tasks, that searches /proc for all child  
> tasks of the process. But then, when I calculate the cpu% of the  
> process, I need to recursively go in and get all the cpu% of all the  
> child threads/processes of the process. And my code got ugly fast.

What is wrong with

class ProcessInfo

def direct\_children  
  
\<return array of ProcessInfo or []\>  
end

def children  
direct\_children.collect{|ch|ch.chilfren}.flatten!  
end

def cpu\_sum  
sum = cpu\_percentage  
children.each{|ch| sum += ch.cpu\_percentage}  
sum  
end

end

Thanks

Michal

–  
Support the freedom of music!  
Maybe it’s a weird genre … but weird is _not_ illegal.  
Maybe next time they will send a special forces commando  
to your picnic … because they think you are weird.  
[www.music-versus-guns.org](http://www.music-versus-guns.org)[http://en.policejnistat.cz](http://en.policejnistat.cz)

---

<div class="post-metadata">

**Author:** ![joe-dumoulin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9dc877/32.png) [@joe-dumoulin](https://www.ruby-forum.com/u/joe-dumoulin)\
**Post date:** [January 11, 2006, 12:02am UTC](https://www.ruby-forum.com/t/finding-cpu-of-a-linux-task/60829/5 "2006-01-11T00:02:25Z")

</div>

On 1/10/06, Barbier de Reuille P. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> Well, on Linux 2.6, the list of the threads is in :
> 
> /proc/[pid]/task
> 
> But it is not true for Linux 2.4 ☹  
> And on 2.4, I really don’t know if you can tell a process from a thread  
> from the exterior. At least, I see no difference in the /proc virtual  
> system.

For my purposes, I don’t want to make a distinction between threads  
and processes. I just want an accurate cpu percentage of a running  
program (which includes all of its threads and child processes).

---

<div class="post-metadata">

**Author:** ![joe-dumoulin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9dc877/32.png) [@joe-dumoulin](https://www.ruby-forum.com/u/joe-dumoulin)\
**Post date:** [January 10, 2006, 11:53pm UTC](https://www.ruby-forum.com/t/finding-cpu-of-a-linux-task/60829/6 "2006-01-10T23:53:17Z")

</div>

Well, on Linux 2.6, the list of the threads is in :

/proc/[pid]/task

But it is not true for Linux 2.4 ☹  
And on 2.4, I really don’t know if you can tell a process from a thread  
from the exterior. At least, I see no difference in the /proc virtual  
system.

But then, this discussion should be in  
comp.os.linux.development.system, isn’t it ?

Pierre

On Wed, 11 Jan 2006 06:42:54 +0900

---

<div class="post-metadata">

**Author:** ![joe-dumoulin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9dc877/32.png) [@joe-dumoulin](https://www.ruby-forum.com/u/joe-dumoulin)\
**Post date:** [January 11, 2006, 12:29am UTC](https://www.ruby-forum.com/t/finding-cpu-of-a-linux-task/60829/7 "2006-01-11T00:29:30Z")

</div>

On Tue, 10 Jan 2006 22:59:27 -0000, Joe Van D. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> For my purposes, I don’t want to make a distinction between threads  
> and processes. I just want an accurate cpu percentage of a running  
> program (which includes all of its threads and child processes).

Since you’re looking in /proc anyway I guess this is for unixy systems,  
so  
_maybe_ the following is of use?

```
module Process
  class << self
    def cpu_percent(pid)
      pgid = getpgid(pid)
      ps = `ps -Ao pcpu,pgrp`.to_a
      (ps[1..-1]).inject(0.0) do |sum,s|
        if s =~ /([\d.]+)\s*([\d]+)/
          tcpu, tpgid = $~.captures
          (tpgid.to_i == pgid) ? sum + tcpu.to_f: sum
        end
      end
    end
  end
end

pid = (ARGV[0] || Process.pid).to_i
puts "#{pid}: #{Process.cpu_percent(pid)}"

```

Not a particularly clean one but maybe it gives a starting point? On my  
system a quick test gives:

```
$ ps -o cmd,pcpu,pid,pgrp,sid
CMD %CPU PID PGRP SID
bash 0.0 4540 4540 4540
ruby -e fork { loop do 1000 2.2 4942 4942 4540
ruby -e fork { loop do 1000 4.3 4943 4942 4540
ps -o cmd,pcpu,pid,pgrp,sid 0.0 5393 5393 4540

$ ruby pinfo.rb 4942
4942: 6.5%

$ ruby pinfo.rb 4294
pinfo.rb:4:in `getpgid': No such process (Errno::ESRCH)
        from pinfo.rb:4:in `cpu_percent'
        from pinfo.rb:17

```

(that second one is a deliberate example 🙂 )

Check out ‘man ps’ for the different args etc, and the proper output  
format syntax if you’re on non-GNU.

---

<div class="post-metadata">

**Author:** ![joe-dumoulin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9dc877/32.png) [@joe-dumoulin](https://www.ruby-forum.com/u/joe-dumoulin)\
**Post date:** [January 11, 2006, 12:47am UTC](https://www.ruby-forum.com/t/finding-cpu-of-a-linux-task/60829/8 "2006-01-11T00:47:34Z")

</div>

On 1/10/06, Joe Van D. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > However, that doesn’t capture threads or forked processes. If a
> 
> =\> false  
> ls: cannot read symbolic link /proc/5463/exe: Permission denied  
> lrwxrwxrwx 1 root games 0 Jan 10 15:26 root  
> TracerPid: 0  
> VmLib: 11512 kB  
> SigPnd: 0000000000000000  
> ShdPnd: 0000000000000000  
> SigBlk: 0000000000000000  
> SigIgn: 0000000000001000  
> SigCgt: 0000000080002e47  
> CapInh: 00000000ffffffff  
> CapPrm: 00000000ffffffff  
> CapEff: 00000000ffffffff

Solved! I thought Ruby was being weird, shame on me.

Threads are represented in /proc with a ‘.’ in front of the id. i.e.  
/proc/.5463. For some reason though, I can access /proc/5463, but  
/proc/5463 doesn’t show up in directory globs.

Joe

---

<div class="post-metadata">

**Author:** ![joe-dumoulin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9dc877/32.png) [@joe-dumoulin](https://www.ruby-forum.com/u/joe-dumoulin)\
**Post date:** [January 11, 2006, 12:32am UTC](https://www.ruby-forum.com/t/finding-cpu-of-a-linux-task/60829/9 "2006-01-11T00:32:31Z")

</div>

On 1/10/06, Joe Van D. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> program starts a couple threads (or forks a child process), I then  
> have to figure out the cpu percentage of each of the child threads  
> (and their childs and their child’s childs, and so on) and add them  
> together to get a total for the process.
> 
> I’m struggling to come up with an elegant way to solve this problem. Any ideas?

I can’t make heads or tails out of this behavior. 5463 is a thread,  
btw. Linux 2.4.21, Ruby 1.8.4. When I do a directory glob of /proc/,  
5463 isn’t coming up.

irb(main):002:0\> File.directory? “/proc/5463”  
=\> true

irb(main):003:0\> Dir[“/proc/5\*”].sort  
=\> [“/proc/5”, “/proc/5111”, “/proc/5113”, “/proc/5459”, “/proc/5470”,  
“/proc/5477”, “/proc/5486”, “/proc/5487”, “/proc/5653”, “/proc/5654”,  
“/proc/5800”, “/proc/5810”, “/proc/5811”]

irb(main):004:0\> Dir[“/proc/5\*”].include?(“/proc/5463”)  
=\> false

irb(main):005:0\> # WTF  
irb(main):006:0\* exit

% ls -ld /proc/5463  
dr-xr-xr-x 3 root games 0 Jan 10 15:26 /proc/5463/

% ls -l /proc/5463  
ls: cannot read symbolic link /proc/5463/cwd: Permission denied  
ls: cannot read symbolic link /proc/5463/root: Permission denied  
ls: cannot read symbolic link /proc/5463/exe: Permission denied  
total 0  
-r–r–r-- 1 root games 0 Jan 10 15:26 cmdline  
-r–r–r-- 1 root games 0 Jan 10 15:26 cpu  
lrwxrwxrwx 1 root games 0 Jan 10 15:26 cwd  
-r-------- 1 root games 0 Jan 10 15:26 environ  
lrwxrwxrwx 1 root games 0 Jan 10 15:26 exe  
dr-x------ 2 root games 0 Jan 10 15:26 fd/  
-r-------- 1 root games 0 Jan 10 15:26 maps  
-rw------- 1 root games 0 Jan 10 15:26 mem  
-r–r–r-- 1 root games 0 Jan 10 15:26 mounts  
lrwxrwxrwx 1 root games 0 Jan 10 15:26 root  
-r–r–r-- 1 root games 0 Jan 10 15:26 stat  
-r–r–r-- 1 root games 0 Jan 10 15:26 statm  
-r–r–r-- 1 root games 0 Jan 10 15:26 status

% cat /proc/5463/status  
Name: sccng.x  
State: S (sleeping)  
Tgid: 5459  
Pid: 5463  
PPid: 5459  
TracerPid: 0  
Uid: 0 0 0 0  
Gid: 20 20 20 20  
FDSize: 256  
Groups: 0 1 2 3 4 6 10 1 2 3 4  
VmSize: 147612 kB  
VmLck: 147612 kB  
VmRSS: 146648 kB  
VmData: 58268 kB  
VmStk: 776 kB  
VmExe: 468 kB  
VmLib: 11512 kB  
SigPnd: 0000000000000000  
ShdPnd: 0000000000000000  
SigBlk: 0000000000000000  
SigIgn: 0000000000001000  
SigCgt: 0000000080002e47  
CapInh: 00000000ffffffff  
CapPrm: 00000000ffffffff  
CapEff: 00000000ffffffff
