The top
command computes the CPU usage using the data in the proc file system. The actual file containing the CPU usage data can vary from one platform to another. For example, in Linux it is found in /proc/<pid>/stat
and for Solaris it is found in /proc/<pid>/psinfo
. The CPU usage is calculated as the difference in cumulative CPU time for a process divided by the amount of time measured between updates.
For Linux, you can inspect the procps source which includes ps
, top
, and other process tool from http://procps.sourceforge.net. The readproc.c file in particular contains the functionality for retrieving the data.
For Solaris, you can inspect the libproc source from https://hg.java.net/hg/solaris~on-src/file/tip/usr/src/lib/libproc. The prog_get_info.c file contains the functionality for retrieving the data and storing it in a psinfo_t
struct.
For Linux, Solaris, and others, you can inspect the Unix Top source from http://sourceforge.net/projects/unixtop. The platform-specific source files within the machine
directory contain the functionality for retrieving the data.
Update
Another option (Solaris only) for retrieving CPU time for a process may be passing to the PIOCPSINFO
or PIOCSTATUS
option to the ioctl()
system call. The PIOCPSINFO
option returns miscellaneous process information in a prpsinfo_t
struct. The PIOCSTATUS
option returns status information for the process in a prstatus_t
struct.
Adapted from example code at http://getthegood.com/TechNotes/Papers/ProcStatistics.html:
int main(int argc, char* argv[])
{
int fd;
prpsinfo_t info;
prstatus_t status;
char procbuf[50];
sprintf(procbuf, "/proc/%d", getpid());
fd = open(procbuf, O_RDONLY);
ioctl(fd, PIOCPSINFO, &info);
printf("Process user+sys time = %ld sec %ld nsec
"
"Reaped children user+sys time = %ld sec %ld nsec
",
info.pr_time.tv_sec, info.pr_time.tv_nsec,
info.pr_ctime.tv_sec, info.pr_ctime.tv_nsec);
ioctl(fd, PIOCSTATUS, &status);
printf("Process user+sys time = %ld sec %ld nsec
"
"Sum of children's user+sys time = %ld sec %ld nsec
",
status.pr_utime.tv_sec+status.pr_stime.tv_sec,
status.pr_utime.tv_nsec+status.pr_stime.tv_nsec,
status.pr_cutime.tv_sec+status.pr_cstime.tv_sec,
status.pr_cutime.tv_nsec+status.pr_cstime.tv_nsec);
close(fd);
exit(0);
}
Note: This code is untested and omits error checking for simplicity.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…