[ 永遠的UNIX::UNIX技術資料的寶庫 ]   GB | BIG5

首頁 > 編程技術 > C/C++ > 正文
Unix編程/應用問答中文版 ---4.系統資源相關問題
本文出自:http://www.nsfocus.com 維護:小四 (2002-10-22 06:02:00)

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,普通用戶用戶無法使用該程序。 
(http://www.fanqiang.com)
    進入【UNIX論壇

相關文章
Unix編程/應用問答中文版 ---3.-lelf、-lkvm、-lkstat相關問題 (2002-10-21 06:02:01)
Unix編程/應用問答中文版 ---2.堆棧相關問題 (2002-10-18 06:02:00)
Unix編程/應用問答中文版 ---1.系統管理配置問題 (2002-10-17 06:02:00)
Unix編程/應用問答中文版 ---0.簡介 Unix/C傳奇問題 (2002-10-16 06:02:01)
 

★  樊強制作 歡迎分享  ★