使用来自C的系统调用,如何获得CPU的利用率?

问题描述:

在FreeBSD上的C中,如何访问CPU利用率?使用来自C的系统调用,如何获得CPU的利用率?

我正在编写一些代码来处理HTTP重定向。如果CPU负载超过FReeBSD系统的阈值,我想重定向客户端请求。查看手册页,kvm_getpcpu()似乎是正确的答案,但手册页(我阅读)没有记录使用情况。

任何提示或指针将受到欢迎 - 谢谢!


在阅读了这里的答案后,我能够拿出下面的内容。由于文档较差,我不能100%确定它是正确的,但顶端似乎同意。感谢所有回答的人。

#include <stdio.h> 
#include <string.h> 
#include <sys/types.h> 
#include <sys/sysctl.h> 
#include <unistd.h> 

#define CP_USER 0 
#define CP_NICE 1 
#define CP_SYS 2 
#define CP_INTR 3 
#define CP_IDLE 4 
#define CPUSTATES 5 

int main() 
{ 
     long cur[CPUSTATES], last[CPUSTATES]; 
     size_t cur_sz = sizeof cur; 
     int state, i; 
     long sum; 
     double util; 

     memset(last, 0, sizeof last); 

     for (i=0; i<6; i++) 
     { 
       if (sysctlbyname("kern.cp_time", &cur, &cur_sz, NULL, 0) < 0) 
       { 
         printf ("Error reading kern.cp_times sysctl\n"); 
         return -1; 
       } 

       sum = 0; 
       for (state = 0; state<CPUSTATES; state++) 
       { 
         long tmp = cur[state]; 
         cur[state] -= last[state]; 
         last[state] = tmp; 
         sum += cur[state]; 
       } 

       util = 100.0L - (100.0L * cur[CP_IDLE]/(sum ? (double) sum : 1.0L)); 
       printf("cpu utilization: %7.3f\n", util); 
       sleep(1); 
     } 

     return 0; 
} 

从该名男子页

NAME

kvm_getmaxcpu,kvm_getpcpu - 访问每个CPU的数据

内核数据访问库(libkvm,-lkvm)

概要

#include <sys/param.h> 
#include <sys/pcpu.h> 
#include <sys/sysctl.h> 
#include <kvm.h> 

int 
kvm_getmaxcpu(kvm_t *kd); 

void * 
kvm_getpcpu(kvm_t *kd, int cpu); 

说明

的kvm_getmaxcpu()和kvm_getpcpu()函数用于访问由KD表示的内核活动处理器的 每个CPU的数据。 kvm_getmaxcpu()函数返回内核支持的最大CPU数。 kvm_getpcpu()函数返回一个缓冲区,用于保存单个CPU的每个CPU的CPU数据。该缓冲区由struct pcpu 类型描述。当呼叫者不再需要时,呼叫者负责通过免费呼叫 释放缓冲区(3)。如果cpu未处于活动状态,则返回空值 。

CACHING

这些功能缓存其 在连续调用重用各种内核变量的值NLIST。您可以调用kd设置为 的函数为NULL来清除此缓存。

返回值

成功时,kvm_getmaxcpu()函数返回的内核支持 的CPU的最大数量。如果发生错误,则返回-1。

成功时,kvm_getpcpu()函数返回指向分配的 缓冲区或NULL的指针。如果发生错误,则返回-1。

如果任一功能遇到错误,则一个错误消息可以是经由kvm_geterr检索


EDIT

这里的kvm_t结构(3):

struct __kvm { 
    /* 
    * a string to be prepended to error messages 
    * provided for compatibility with sun's interface 
    * if this value is null, errors are saved in errbuf[] 
    */ 
    const char *program; 
    char *errp;   /* XXX this can probably go away */ 
    char errbuf[_POSIX2_LINE_MAX]; 
    #define ISALIVE(kd) ((kd)->vmfd >= 0) 
    int  pmfd;   /* physical memory file (or crashdump) */ 
    int  vmfd;   /* virtual memory file (-1 if crashdump) */ 
    int  unused;   /* was: swap file (e.g., /dev/drum) */ 
    int  nlfd;   /* namelist file (e.g., /kernel) */ 
    struct kinfo_proc *procbase; 
    char *argspc;   /* (dynamic) storage for argv strings */ 
    int  arglen;   /* length of the above */ 
    char **argv;   /* (dynamic) storage for argv pointers */ 
    int  argc;   /* length of above (not actual # present) */ 
    char *argbuf;  /* (dynamic) temporary storage */ 
    /* 
    * Kernel virtual address translation state. This only gets filled 
    * in for dead kernels; otherwise, the running kernel (i.e. kmem) 
    * will do the translations for us. It could be big, so we 
    * only allocate it if necessary. 
    */ 
    struct vmstate *vmst; 
}; 

我不知道确切的库,命令或系统调用;然而,如果你真的陷入困境,请将源代码下载到顶端。它使用“-P”标志显示per-cpu统计信息,并且必须从某处获取该信息。

我相信你想看看'man sysctl'。

+0

谢谢 - 这非常有帮助! – 2011-03-17 00:47:52