作者:不祥 [文章出自: www.fanqiang.com]
4. 系统资源相关问题
4.1 主流Unix操作系统上如何编程获取进程的内存、CPU利用状况
4.2 Solaris下如何获知CPU速率
4.3 如何编程获取Solaris系统当前内存大小
--------------------------------------------------------------------------
4. 系统资源相关问题
4.1 主流Unix操作系统上如何编程获取进程的内存、CPU利用状况
Q: Solaris下如何编程获知CPU占用率和内存占用信息呢,可移植吗?
Q: 我想写个程序遍历当前运行中的活动进程,Solaris提供相应系统调用了吗
A: Nicholas Dronen <ndronen@io.frii.com>
不可移植。man -s 4 proc,man -s 3k kstat
如果不是编程,可以用top、mpstat、vmstat、sar(1)等等,还有
/usr/ucb/ps -aux,对于Solaris来说,后者更直接精炼,top不是标准配置。
# /usr/bin/prstat (Solaris 8 prstat(1M)手册页)
# /usr/ucb/ps -aux | head (Solaris 2.x)
Q: 主流Unix操作系统上如何编程获取进程的内存、CPU利用状况,AIX、HP、SUN
process memory usage
process cpu time usage
A: Nate Eldredge <neldredge@hmc.edu>
man -s 3C getrusage
D: 小四 <cloudsky@263.net>
在SPARC/Solaris 2.6/7下结论一致,只支持了ru_utime和ru_stime成员,其他成员
被设置成0。FreeBSD 4.3-RELEASE上测试,则不只支持ru_utime和ru_stime成员。从
FreeBSD的getrusage(2)手册页可以看到,这个函数源自4.2 BSD。
至少对于SPARC/Solaris 2.6/7,getrusage(3C)并无多大意义。
A: Robert Owen Thomas <robt@cymru.com>
对于Solaris,可以利用procfs接口,下面的例子获取指定进程的内存占用情况
--------------------------------------------------------------------------
/*
* @(#)memlook.c 1.0 10 Nov 1997
* Robert Owen Thomas robt@cymru.com
* memlook.c -- A process memory utilization reporting tool.
*
* gcc -Wall -O3 -o memlook memlook.c
*/
#pragma ident "@(#)memlook.c 1.0 10 Nov 1997 Robert Owen Thomas robt@cymru.com"
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/signal.h>
#include <sys/syscall.h>
#include <sys/procfs.h>
#include <sys/param.h>
#include <unistd.h>
#include <fcntl.h>
int counter = 10;
int showUsage ( const char * );
void getInfo ( int, int );
int main ( int argc, char * argv[] )
{
int fd, pid, timeloop = 0;
char pidpath[BUFSIZ]; /* /usr/include/stdio.h: #define BUFSIZ 1024 */
switch ( argc )
{
case 2:
break;
case 3:
timeloop = atoi( argv[2] );
break;
default:
showUsage( argv[0] );
break;
} /* end of switch */
pid = atoi( argv[1] );
sprintf( pidpath, "/proc/%-d", pid ); /* -表示向左靠 */
/*
* /proc/1/是目录,但在这种用法中,就是直接打开目录,不是打开文件
*/
if ( ( fd = open( pidpath, O_RDONLY ) ) < 0 )
{
perror( pidpath );
exit( 1 );
}
if ( 0 < timeloop )
{
for ( ; ; )
{
getInfo( fd, pid );
sleep( timeloop );
}
}
getInfo( fd, pid );
close( fd );
exit( 0 );
} /* end of main */
int showUsage ( const char * progname )
{
fprintf( stderr, "%s: usage: %s < PID > [time delay]\\n", progname, progname
);
exit( 3 );
} /* end of showUsage */
void getInfo ( int fd, int pid )
{
prpsinfo_t prp;
prstatus_t prs;
if ( ioctl( fd, PIOCPSINFO, &prp ) < 0 )
{
perror( "ioctl" );
exit( 5 );
}
if ( ioctl( fd, PIOCSTATUS, &prs ) < 0 )
{
perror( "ioctl" );
exit( 7 );
}
if ( counter > 9 )
{
fprintf( stdout, "PID\\tIMAGE\\t\\tRSS\\t\\tHEAP\\t\\tSTACK\\n" );
counter = 0;
}
fprintf( stdout, "%u\\t%-9u\\t%-9u\\t%-15u\\t%-15u\\n", pid,
( unsigned int )prp.pr_bysize, ( unsigned int )prp.pr_byrssize,
( unsigned int )prs.pr_brksize, ( unsigned int )prs.pr_stksize );
counter++;
} /* end of getInfo */
--------------------------------------------------------------------------
4.2 Solaris下如何获知CPU速率
A: Philip Brown <phil+s3@bolthole.no-bots.com>
psrinfo -v
psrinfo | grep on-line | wc -l 简单给出CPU数目
A: scz <scz@nsfocus.com>
# /usr/platform/`uname -i`/sbin/prtdiag -v
# /usr/platform/`uname -m`/sbin/prtdiag -v
# /usr/bin/netstat -k cpu_info0
A: Tony Walton <tony.walton@uk.sun.com>
如果你装了Sun Workshop,还可以尝试fpversion命令
# /opt/SUNWspro/bin/fpversion
A SPARC-based CPU is available.
CPU's clock rate appears to be approximately 266.1 MHz.
Kernel says CPU's clock rate is 270.0 MHz.
Kernel says main memory's clock rate is 90.0 MHz.
Sun-4 floating-point controller version 0 found.
An UltraSPARC chip is available.
FPU's frequency appears to be approximately 277.1 MHz.
Use "-xtarget=ultra2i -xcache=16/32/1:256/64/1" code-generation option.
Hostid = 0x80BC3CB3.
#
4.3 如何编程获取Solaris系统当前内存大小
Q: 如何编程(或者有什么现成命令)获取Solaris系统当前内存大小?
A: Nithyanandham <m.nithyanandham@blr.spcnl.co.in>
几个现成命令
/usr/platform/`uname -m`/sbin/prtdiag -v | grep Memory
prtconf -v | grep Memory
如果装了GNU top,也可以直接用top命令看到。
D: scz <scz@nsfocus.com>
truss prtconf的输出中有如下内容
sysconfig(_CONFIG_PAGESIZE) = 8192
sysconfig(_CONFIG_PHYS_PAGES) = 16384
Memory size: 128 Megabytes
# /usr/ccs/bin/nm -nx /dev/ksyms | grep "|sysconfig$"
10626] |0x0000100ec110|0x0000000001bc|FUNC |GLOB |0 |ABS |sysconfig
# find /usr/include -type f -name "*.h" | xargs grep -l _CONFIG_PAGESIZE
/usr/include/sys/sysconfig.h
# vi -R /usr/include/sys/sysconfig.h
/*
* cmd values for _sysconfig system call.
* WARNING: This is an undocumented system call,
* therefore future compatibility can not
* guaranteed.
*/
#define _CONFIG_PAGESIZE 6 /* system page size */
#define _CONFIG_PHYS_PAGES 26 /* phys mem installed in pages */
参看sysconf(3C)手册页。
_SC_PAGESIZE
_SC_PAGE_SIZE
_SC_PHYS_PAGES
A: Casper Dik <Casper.Dik@Holland.Sun.COM>
--------------------------------------------------------------------------
/*
* Program to determine the size installed physical memory on Suns.
*
* Casper Dik.
*/
#define MEGABYTE 0x00100000
#define MAXMEM 0x7ff00000
#define THEMEM "/dev/mem"
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <unistd.h>
int main ( int argc, char * argv[] )
{
int fd = open( THEMEM, O_RDONLY );
char c;
unsigned long pos, mapstart = 0;
int totmb = 0;
if ( fd == -1 )
{
perror( THEMEM );
exit( 1 );
}
for ( pos = 0; pos < MAXMEM; pos += MEGABYTE )
{
if (lseek( fd, pos, 0 ) == -1 )
{
perror( "lseek" );
exit( 1 );
}
if ( read( fd, &c, 1 ) == -1 )
{
int size = ( pos - mapstart ) / MEGABYTE;
if ( size != 0 )
{
printf( "found %3d MB starting at 0x%p\\n", size, ( void * )mapst
art );
totmb += size;
}
mapstart = pos + MEGABYTE; /* start of next possible mapping */
}
}
printf( "Total memory size: %d MB\\n", totmb );
exit( 0 );
}
--------------------------------------------------------------------------
由于需要读访问/dev/mem,普通用户用户无法使用该程序。