Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C程序获取PID及其所有子级的CPU使用率_C_Linux_Profiling - Fatal编程技术网

C程序获取PID及其所有子级的CPU使用率

C程序获取PID及其所有子级的CPU使用率,c,linux,profiling,C,Linux,Profiling,我有一个C程序,它解析/proc//stat目录以计算5秒钟内的平均CPU利用率: #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #define ITERATIONS 5 int main(int argc, char *argv[]) { if (argc != 2) { printf( "usage: %s

我有一个C程序,它解析/proc//stat目录以计算5秒钟内的平均CPU利用率:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#define ITERATIONS 5

int main(int argc, char *argv[])
{
    if (argc != 2) {
        printf( "usage: %s <PID>\n", argv[0] );
        return(-1);
    }

    long double a[4], b[4];
    long double pidTime = 0.0;
    long int clk;
    int i;
    FILE *fp;
    char stat[1024];

    clk = sysconf(_SC_CLK_TCK);

    if (clk == -1) {
        printf("Could not determine clock ticks per second");
        return(-1);
    }

    char *pidPath = malloc(strlen("/proc/stat/")+strlen(argv[1])+1);
    if (pidPath == NULL) {
        printf("Could not allocate memory for str\n");
        return(-1);
    } else {
        strcpy(pidPath, "/proc/");
        strcat(pidPath, argv[1]);
        strcat(pidPath, "/stat");
    }

    for(i = 0; i < ITERATIONS; i++)
    {
        fp = fopen(pidPath,"r");
        if (fp == NULL) {
            perror(pidPath);
            return(-1);
        } else {
            fgets(stat, sizeof(stat), fp);
            sscanf(stat,"%*d %*s %*c %*d %*d %*d %*d %*d %*u %*lu %*lu %*lu %*lu %Lf %Lf %Lf %Lf %*ld %*ld %*ld %*ld %*llu",&a[0],&a[1],&a[2],&a[3]);
            fclose(fp);
            sleep(1);
        }

        fp = fopen(pidPath,"r");
        if (fp == NULL) {
            perror(pidPath);
            return(-1);
        } else {
            fgets(stat, sizeof(stat), fp);
           sscanf(stat,"%*d %*s %*c %*d %*d %*d %*d %*d %*u %*lu %*lu %*lu %*lu %Lf %Lf %Lf %Lf %*ld %*ld %*ld %*ld %*llu",&b[0],&b[1],&b[2],&b[3]);
            fclose(fp);
        }

        pidTime += (((b[0]+b[1]+b[2]+b[3]) - (a[0]+a[1]+a[2]+a[3])));
    }

    pidTime = (pidTime / (clk * ITERATIONS));
    printf("pidCPU=%Lf\n", pidTime);
    printf("%ld", clk);
    free(pidPath);
    return(0);
}
#包括
#包括
#包括
#包括
#定义迭代5
int main(int argc,char*argv[])
{
如果(argc!=2){
printf(“用法:%s\n”,argv[0]);
返回(-1);
}
长双a[4],b[4];
长双PID时间=0.0;
龙内时钟;
int i;
文件*fp;
字符统计[1024];
clk=sysconf(_SC_clk_TCK);
如果(时钟==-1){
printf(“无法确定每秒的时钟滴答声”);
返回(-1);
}
char*pidPath=malloc(strlen(“/proc/stat/”)+strlen(argv[1])+1);
if(pidPath==NULL){
printf(“无法为str分配内存\n”);
返回(-1);
}否则{
strcpy(pidPath,“/proc/”);
strcat(pidPath,argv[1]);
strcat(pidPath,“/stat”);
}
对于(i=0;i
据我所知,stat中的相关字段包括:

  • int-utime;/**用户模式jiffies**/

  • 整数时间;/**内核模式jiffies**/

  • 内部表皮;/**带孩子的用户模式jiffies**/

  • int cstime;/**带childs的内核模式jiffies**/


对于单个进程来说,这非常有效,但是当我有一个分叉的或多线程的进程时,它就崩溃了。cutime和cstime计数器是否仅在父进程等待子进程时工作?如何计算以PID为根的进程树的总使用率?

是的,父进程需要等待添加子进程的CPU时间(请参阅
getrusage
的手动输入)。有关更多详细信息,请参见。

为什么不在
stderr
上输出错误?@Ascam我应该这样做,我想我只是在这一点上懒惰。不过你是对的。不管怎样,只要遵循逻辑,因为你在跟踪一个PID,你只会得到关于这个PID的信息。每个子进程都是一个。。。进程,您可以通过它们自己的ID来引用它们。我的最后一点是:是的,您只能看到一些
等待
活动监视家长,这似乎很正常。那么有没有办法从/proc获取进程树呢?如果是这样的话,我可能会在一些内核上使用递归解决方案,您可以从
/proc/**pid**/task/**taskid**/children
文件中获取子级。否则,可以从父pid执行反向查找。父pid列在第
PPid
行的
/proc/*pid*/status
中。您可以使用以下命令从shell进行尝试:
fgrep PPid/proc/[0-9]*/status 2>/dev/null | fgrep$$| cut-d/-f3
,该命令应列出shell的子进程(
$
)。请注意,grep/cut本身将显示在此列表中,但这些过程将在提示符返回时消失。