简体   繁体   English

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

[英]Using system calls from C, how do I get the utilization of the CPU(s)?

In C on FreeBSD, how does one access the CPU utilization? 在FreeBSD上的C中,如何访问CPU利用率?

I am writing some code to handle HTTP redirects. 我正在编写一些代码来处理HTTP重定向。 If the CPU load goes above a threshold on a FReeBSD system, I want to redirect client requests. 如果CPU负载超过FReeBSD系统的阈值,我想重定向客户端请求。 Looking over the man pages, kvm_getpcpu() seems to be the right answer, but the man pages (that I read) don't document the usage. 查看手册页,kvm_getpcpu()似乎是正确的答案,但是手册页(我读过)没有记录用法。

Any tips or pointers would be welcome - thanks! 欢迎任何提示或指示 - 谢谢!


After reading the answers here, I was able to come up with the below. 在阅读了这里的答案后,我能够提出以下内容。 Due to the poor documentation, I'm not 100% sure it is correct, but top seems to agree. 由于文档很差,我不是100%肯定它是正确的,但顶部似乎同意。 Thanks to everyone who answered. 感谢所有回答的人。

#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;
}

From the MAN pages 从MAN页面

NAME 名称

kvm_getmaxcpu, kvm_getpcpu -- access per-CPU data kvm_getmaxcpu,kvm_getpcpu - 访问每CPU数据

LIBRARY 图书馆

Kernel Data Access Library (libkvm, -lkvm) 内核数据访问库(libkvm,-lkvm)

SYNOPSIS 概要

 #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);

DESCRIPTION 描述

The kvm_getmaxcpu() and kvm_getpcpu() functions are used to access the per-CPU data of active processors in the kernel indicated by kd. kvm_getmaxcpu()和kvm_getpcpu()函数用于访问由kd指示的内核中的活动处理器的每CPU数据。 The kvm_getmaxcpu() function returns the maximum number of CPUs supported by the kernel. kvm_getmaxcpu()函数返回内核支持的最大CPU数。 The kvm_getpcpu() function returns a buffer holding the per- CPU data for a single CPU. kvm_getpcpu()函数返回一个缓冲区,其中包含单个CPU的每CPU数据。 This buffer is described by the struct pcpu type. 此缓冲区由struct pcpu类型描述。 The caller is responsible for releasing the buffer via a call to free(3) when it is no longer needed. 当不再需要时,调用者负责通过调用free(3)来释放缓冲区。 If cpu is not active, then NULL is returned instead. 如果cpu未激活,则返回NULL。

CACHING CACHING

These functions cache the nlist values for various kernel variables which are reused in successive calls. 这些函数缓存在连续调用中重用的各种内核变量的nlist值。 You may call either function with kd set to NULL to clear this cache. 您可以调用kd设置为NULL的任一函数来清除此缓存。

RETURN VALUES 返回值

On success, the kvm_getmaxcpu() function returns the maximum number of CPUs supported by the kernel. 成功时,kvm_getmaxcpu()函数返回内核支持的最大CPU数。 If an error occurs, it returns -1 instead. 如果发生错误,则返回-1。

On success, the kvm_getpcpu() function returns a pointer to an allocated buffer or NULL. 成功时,kvm_getpcpu()函数返回指向已分配缓冲区的指针或NULL。 If an error occurs, it returns -1 instead. 如果发生错误,则返回-1。

If either function encounters an error, then an error message may be retrieved via kvm_geterr(3.) 如果任一函数遇到错误,则可以通过kvm_geterr(3)检索错误消息。


EDIT 编辑

Here's the kvm_t struct: 这是kvm_t结构:

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;
};

我相信你想要研究'man sysctl'。

I don't know the exact library, command, or system call; 我不知道确切的库,命令或系统调用; however, if you really get stuck, download the source code to top. 但是,如果你真的遇到困难,请将源代码下载到顶部。 It displays per-cpu stats when you use the "-P" flag, and it has to get that information from somewhere. 当您使用“-P”标志时,它会显示每个cpu的统计信息,并且它必须从某个地方获取该信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM