查看线程的cpu使用率

来源:互联网 发布:php项目部署到apache 编辑:程序博客网 时间:2024/04/28 09:30

        busybox 中的top 不支持查看线程, 因此查询相关资料自己写了一个, 对比测试跟linux 标准的top数据一致。另外,需要注意的是,

 pthread_create(&task_id,...) 的task_id和tid不同,
需要做一个对应:
 #include <sys/syscall.h>
 printf("%u --> tid %u\n", pthread_self(), syscall(SYS_gettid));

 

不啰嗦了,附源码:

/* top_thread.c -- mimic "top -H -p pid" * author: ludi 2013.11doc: $ cat /proc/statcpu  3723999 28230 813821 136182538 6215783 187445         373893  0      user,  nice,   sys,     idle,     irq, softirq, stealstolen, guest$ cat /proc/31628/stat31628 (pdflush) S 19 1 1 0 -1 8400960 0 0 0 0  0 161 0 0  15 0 1  0 36070699 0 0 4294967295 0 0 0 0   0 0 2147483647 65536 0 0 0 0 17 2 0 0 2648$ cat /proc/31628/task/31628/stat31628 (pdflush) S 19 1 1 0 -1 8400960 0 0 0 0  0 161 0 0  15 0 1  0 36070699 0 0 4294967295 0 0 0 0   0 0 2147483647 65536 0 0 0 0 17 2 0 0 2648 1      2       3 4  5 6 7 8   9      10--13  14------17  18-20   21-----------------------------29   30---------------33pid comm state ppid pgid sid tty_nr tty_pgrp 1-8flags 9flt_{min, cmin, maj, cmaj}10-13time_{u,s,cu,cs} 14-17priority nice num_threads 18-20start_time vsize mm rsslim start_code end_code start_stack esp eip 21-29sig_{pending, blocked, ign, catch} 30-33ULL totalCpuTime; //from /proc/statULL processCpuTime; //from /proc/<pid>/statULL threadCpuTime; //from /proc/<pid>/task/<tid>/stattotalCpuTime = user + nice + system + idle + iowait + irq + softirq + stealstolen +  guest;processCpuTime = utime + stime + cutime + cstime;threadCpuTime = utime + stime; pthread_create(&task_id,...) 的task_id和tid不同,需要做一个对应: #include <sys/syscall.h>  printf("%u --> tid %u\n", pthread_self(), syscall(SYS_gettid));*/#include <stdio.h>#include <string.h>#include <stdlib.h>#include <unistd.h>#include<sys/stat.h>#include <unistd.h> /*fstat*/#include <dirent.h> /*opendir*/#define THREAD_MAX 512typedef unsigned long long ULL;typedef struct{ULL total, idle;ULL process;int tcnt;unsigned tid[THREAD_MAX];ULL ttime[THREAD_MAX];}cpu_time_t;typedef struct{unsigned tid;float usage;}sorted_time_t;int sorted_time_cmp(const void *a, const void *b){return ((sorted_time_t*)b)->usage - ((sorted_time_t*)a)->usage;}ULL get_ttime(cpu_time_t *ct, unsigned tid){int i;for(i = 0; i < ct->tcnt; ++i){if(ct->tid[i] == tid)return ct->ttime[i];}return 0;}int get_tids(unsigned pid, unsigned tids[], int *cnt){    DIR *dp;    struct dirent *entry;    struct stat statbuf;char dir[64];int num;if(!tids || !cnt){printf("bad arg"); return -1;}sprintf(dir, "/proc/%u/task", pid);if(NULL == (dp = opendir(dir))){        printf("can not open directory :%s\n",dir);        exit( -1);    }num = 0;while(NULL != (entry = readdir(dp))){stat(entry->d_name,&statbuf);if(S_ISDIR(statbuf.st_mode) &&(!strcmp(".",entry->d_name)||!strcmp("..",entry->d_name)) ){continue;}tids[num] = atoi(entry->d_name);num++;if(num >= *cnt){break;}}closedir(dp);*cnt = num;return 0;}int get_processor_cnt(void){FILE *fp;char name[64];int cnt;sprintf(name, "%s", "/proc/cpuinfo");fp = fopen(name, "r");if(!fp){printf("can't open %s\n", name); exit(-1);}cnt = 0;while(fgets(name, sizeof(name), fp)){if(!strncmp(name, "processor", strlen("processor"))||!strncmp(name, "Processor", strlen("Processor")) ){++cnt;}}fclose(fp);if(!cnt){printf("set processor cnt to default 1");cnt = 1;}return cnt;}ULL cpu_time_snap_cpu(ULL *idle_){ULL user, nice, sys, idle, irq, softirq, stealstolen, guest;ULL totalCpuTime;FILE *fp;char name[64];sprintf(name, "%s", "/proc/stat");fp = fopen(name, "r");if(!fp)exit(-1);fscanf(fp, "%*s%llu%llu%llu%llu%llu%llu%llu%llu", &user, &nice, &sys, &idle, &irq, &softirq, &stealstolen, &guest);fclose(fp);totalCpuTime = user + nice + sys + idle + irq + softirq + stealstolen +  guest;*idle_ = idle;return totalCpuTime;}ULL cpu_time_snap_process(ULL pid){ULL utime, stime, cutime, cstime;ULL processCpuTime;FILE *fp;char name[64];sprintf(name, "/proc/%llu/stat", pid);fp = fopen(name, "r");if(!fp)exit(-1);fscanf(fp, "%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s");fscanf(fp, "%llu%llu%llu%llu", &utime, &stime, &cutime, &cstime);fclose(fp);processCpuTime = utime + stime + cutime + cstime;return processCpuTime;}ULL cpu_time_snap_thread(ULL pid, ULL tid){ULL utime, stime, cutime, cstime;ULL threadCpuTime;FILE *fp;char name[64];sprintf(name, "/proc/%llu/task/%llu/stat", pid, tid);fp = fopen(name, "r");if(!fp)return 0;//exit(-1);fscanf(fp, "%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s");fscanf(fp, "%llu%llu%llu%llu", &utime, &stime, &cutime, &cstime);fclose(fp);threadCpuTime = utime + stime;return threadCpuTime;}ULL cpu_time_snap(unsigned pid){static int is_first = 1, processor_cnt = 0;static cpu_time_t last_ct = {0};static sorted_time_t st[THREAD_MAX];ULL delta_totalCpuTime, delta_idle, delta_processCpuTime, delta_threadCpuTime;cpu_time_t ct = {0};float pcpu[4];int i;if(is_first){processor_cnt = get_processor_cnt();}ct.tcnt = THREAD_MAX;get_tids(pid, ct.tid, &ct.tcnt);ct.total = cpu_time_snap_cpu(&ct.idle);ct.process = cpu_time_snap_process(pid);for(i = 0; i < ct.tcnt; ++i){ct.ttime[i] = cpu_time_snap_thread(pid, ct.tid[i]);}if(is_first)goto _end;delta_totalCpuTime = ct.total - last_ct.total;delta_idle = ct.idle - last_ct.idle;delta_processCpuTime = ct.process - last_ct.process;if(!delta_totalCpuTime)return 0;//cpu usagepcpu[0] = 100*(delta_totalCpuTime - delta_idle)/(float)delta_totalCpuTime *processor_cnt;//process usagepcpu[1] = 100*delta_processCpuTime/(float)delta_totalCpuTime *processor_cnt;printf("\033[H\033[J");printf("cpu %.2f process %.2f\n", pcpu[0], pcpu[1]); //thread usagefor(i = 0; i < ct.tcnt; ++i){delta_threadCpuTime = ct.ttime[i] - get_ttime(&last_ct, ct.tid[i]);pcpu[2] = 100*delta_threadCpuTime/(float)delta_totalCpuTime *processor_cnt;st[i].tid = ct.tid[i];st[i].usage = pcpu[2];}qsort(st, ct.tcnt, sizeof(st[0]), sorted_time_cmp);for(i = 0; i < ct.tcnt; ++i){printf("%u:%.2f\t", st[i].tid, st[i].usage);}printf("tcnt %d", ct.tcnt);fflush(stdout);_end:last_ct = ct;is_first = 0;return delta_totalCpuTime;}int main(int argc, char **argv){int i;//Hertz = sysconf(_SC_CLK_TCK);//printf("HZ %u\n", Hertz);if(argc < 2){return printf("usage: topH pid\n");}cpu_time_snap(atoi(argv[1]));for(i = 0; ; ++i){cpu_time_snap(atoi(argv[1]));usleep(1000000*1);}return 0;}

原创粉丝点击