2018年9月10日 星期一

top 指定 program, cpu loading

script
top -p `pgrep -d, -f program1`, `pgrep -d, -f program2`


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

#define DEBUG 0
#define CPU_CORE 2
#define STR_ROW 16
#define STR_LEN 64
#define CSV_FORMAT

typedef struct target
{
    char **cpu;
    char **name;
}target_t;

int STOP_FLAG;

void sigroutine(int dunno)
{
    switch(dunno){
        case SIGINT:
            printf("ctrl-c signal\n");
            STOP_FLAG=1;
        break;
        case SIGTERM:
            printf("terminal signal\n");
            STOP_FLAG=1;
        break;
        case SIGQUIT:
            printf("quit signal\n");
            STOP_FLAG=1;
        break;
        default:
            printf("Unknow signal\n");
    }
}

char **getMem()
{
    int i=0, j=0;
    char **ptr = (char **)malloc(sizeof(char*) * STR_ROW);
    for (i = 0; i <STR_ROW; i++)
        ptr[i] = (char *)malloc(sizeof(char *) * STR_LEN);

    for (i = 0; i <STR_ROW; i++)
        for(j=0; j< STR_LEN; j++)
            ptr[i][j]=0;
    return ptr;
}

int get_count(const char *cmd)
{
    FILE *pp=NULL;
    char buf[32];
    int count=0;
    pp=popen(cmd, "r");
    while (fgets(buf, 255, pp) != NULL)
    {
        //printf("buf=%s", buf);
    }
    sscanf(buf, "%d", &count);
    printf("cound=%d\n", count-1);
    pclose(pp);
    return count-1;
}


int ttop (const char *cmd, char **val)
{
    int i=0,j=0;
    FILE *pp=NULL;
    char buf[32];

    for (i=0; i<STR_ROW; i++)
    {
        for(j=0; j<STR_LEN; j++)
        {
            val[i][j]=0;
        }
    }

    i=0;j=0;
    pp=popen(cmd, "r");
    while (fgets(buf, 255, pp) != NULL)
    {
#if DEBUG
        printf("buf=%s", buf);
#endif
        strncpy(val[i], buf, strlen(buf)-1);
        i++;
    }
    pclose(pp);
    return 0;
}


int do_str (target_t *aim, char **top_str)
{
    int i=0;

    for(i=0; i<STR_ROW; i++)
    {
        if(top_str[i] == NULL)
            break;
        sscanf(top_str[i], "%s %s", aim->cpu[i], aim->name[i]);
    }
#if DEBUG
    for(i=0; i<STR_ROW; i++)
    {
        if(top_str[i] == NULL)
            break;
        printf("cpu_loading=%s, name=%s\n", aim->cpu[i], aim->name[i]);
    }
#endif
    return 0;
}

void analysis (target_t *aim, int count, char *argv[])
{
    int i=0, j=0, k=0;
    //double *total_cpu=(double *)malloc(sizeof(double)*(count-1));
    double cpu[STR_ROW];
    double pcpu=0.0; //signal process cpu loading
    double tcpu=0.0; //total process cpu loading, ex: (A+B)/cpu_core

    for(i=0; i<STR_ROW; i++)
    {
        if((aim->cpu[i] != NULL) && (aim->name[i] != NULL))
        {
            cpu[i]=strtod(aim->cpu[i],NULL);
        }       
    }
    for(j=1; j<count; j++)
    {
#if DEBUG
        printf("aim_name[%d]=%s\n", j, argv[j]);
#endif
        pcpu=0.0;
        for(i=0; i<STR_ROW; i++)
        {
            if (strcmp(aim->name[i], argv[j]) == 0)   
            {
                pcpu+=cpu[i];
                k=i; //for cmd_name
#if DEBUG
                printf("k=%d, cpu_loading=%s, cmd_name=%s\n", i, aim->cpu[i], aim->name[i]);
#endif
            }
        }    
        tcpu+=pcpu;
#ifdef CSV_FORMAT
        if(!strcmp("", aim->name[k]))
            printf("didn't find target name\n");
        else
            printf("%.2lf, %s, ", pcpu, aim->name[k]);
#else
        printf("sum_cpu=%.2lf, name=%s ", pcpu, aim->name[k]);
#endif
        //total_cpu[j-1]=sum_cpu;
    }
#ifdef CSV_FORMAT
    if(strcmp("", aim->name[k]))
        printf("%.2lf, cpu\n", tcpu/CPU_CORE);
#else
    printf("cpu=%.2lf\n", tcpu/CPU_CORE);
#endif
    return;
}

void print_useage(void)
{
    printf("\nPlease enter the target name:\n");
    printf("Btw, 1, The limit is three process names\n");
    printf("     2, the output value takes about 10 seconds\n");
    printf("ex: ./get_top process_name process_name\n");
}

int init (int argc, char *argv[])
{
    if(argc < 2)
    {
        print_useage();
        return 1;    
    }
    if((strcmp(argv[0], "-h")==0) || (strcmp(argv[0], "--help")==0))
    {
        print_useage();
        return 1;    
    }
    return 0;
}

/*
 * "top -n 3 -d 5", the output value takes about 10 seconds
 * (d * (n-1))=5*2=10
 * -n : Number-of-iterations
 *      use 2 because: When you first run it, it has no previous sample to compare to, so these initial values are the percentages since boot.
 * -d : delay-time
 */ 
char *ccmd(int argc, char *argv[], const char *opt, int count)
{
    int i=0;
    char *cmd, *tmp1, *tmp2;
    char *str;
    cmd =(char *)malloc(sizeof(char)*STR_LEN*2);
    tmp1=(char *)malloc(sizeof(char)*STR_LEN*2);
    tmp2=(char *)malloc(sizeof(char)*STR_LEN*2);

    if(!strcmp("top", opt))
        str="top -n 3 -d 5 | grep ";
    else
        str="ps -ef | grep ";

    memset(tmp1, 0, sizeof(char)*STR_LEN*2);
    memset(tmp2, 0, sizeof(char)*STR_LEN*2);

    strcpy(cmd, str);
    int ret=0;
    for(i=0; i<argc-1; i++)
    {
        if( strlen(tmp1) > STR_LEN*2-1)
        {    
            printf("too many target_name\n");
            return NULL; 
        }
        ret=snprintf(tmp1, STR_LEN*2-1, "-e \'%s\' ", argv[i+1]);
        strcat(tmp2, tmp1);
    }

#if DEBUG
    printf("%s, tmp1=%s, tmp2=%s\n", __FUNCTION__, tmp1, tmp2);
#endif

    if(!strcmp("top", opt))
        str="| tail -n %d |";
    else
        str="| grep -v grep | wc -l";

    sprintf(tmp1, str, count);
    strcat(cmd, tmp2);
    strcat(cmd, tmp1);

    if(!strcmp("top", opt))
        str=" awk \'{print $10, $13}\'";
    else
        str="";

    strcat(cmd, str);
#if DEBUG
    printf("%s, cmd=%s\n", __FUNCTION__, cmd);
#endif
    free(tmp1);
    free(tmp2);

    return cmd;
}

int main(int argc, char *argv[])
{
    int i=0;
    int count=0;
    char **top_str = getMem();
    char *cmd;
    target_t aim;

    if(init(argc, argv))
        return 1;

    signal(SIGINT , sigroutine);
    signal(SIGQUIT, sigroutine);
    STOP_FLAG=0;
    
    aim.cpu=getMem(); 
    aim.name=getMem(); 

    cmd=ccmd(argc, argv, "ps", count);
    if (cmd == NULL)
        return 1;
    count=get_count(cmd);
#if 1
    if (count > STR_ROW || count < 0)
    {
        printf("Process more or less, the range is 0~%d\n", STR_LEN);
        return 1;
    }

    cmd=ccmd(argc, argv, "top", count);
    while(!STOP_FLAG)
    {
        ttop(cmd, top_str);
        do_str(&aim, top_str);
        analysis(&aim, argc, argv);
    }

    //free
    for (i = 0; i <STR_ROW; i++)
    {
        free(top_str[i]);
        free(aim.cpu[i]);
        free(aim.name[i]);
    }
#endif
    free(top_str);
    free(aim.cpu);
    free(aim.name);
    free(cmd);

    return 0;
}

copy form Here
ps command (should not use):
top command (should use):
ref:
1. stackoverflow

沒有留言:

張貼留言